找回密码
 注册
关于网站域名变更的通知
查看: 348|回复: 2
打印 上一主题 下一主题

简谈FPGA研发设计相关规范(企业中初入职场很实用)

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2023-5-23 18:17 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
大侠好,欢迎来到FPGA技术江湖,江湖偌大,相见即是缘分。大侠可以关注FPGA技术江湖,在“闯荡江湖”、"行侠仗义"栏里获取其他感兴趣的资源,或者一起煮酒言欢。今天和大侠聊一聊FPGA研发设计相关规范,养成良好的个人习惯,代码设计风格等,都有助于日后发展。有哪些设计规范,从文档到工程建立等,聊一聊也许你会学到很多东西,少走很多弯路哦。话不多说,上货。
3 b4 ~# D5 }* m# q" W: _& L7 x
9 O. Z& N( `2 {1 w  o+ K0 A# m
; O" ^, J3 |; j5 D+ n/ j8 U# ]- N
    在团队项目开发中,为了使开发的高效性、一致性、正确性,团队应当要有一个规范的设计流程。按照规范来完成项目的设计开发工作,归类清晰明了的工程文件夹级别;项目应拥有良好风格和完整的文档,如设计思路与调试记录及器件选型等;代码书写高效,即统一的书写规范,文件头包含的信息完整,无论自己还是团队他人阅读便一目了然。
( s+ L6 j6 r6 n% ]9 f% A- Q( Y
  M( Y6 @" }) n4 F2 d) V1 q
6 @# h! o: `% d6 r$ h5 S' ^
一、文档命名:0 t+ l) j8 v/ Z$ _0 Z$ b

0 \" l9 l2 `6 g. i1 d
# d+ m$ u1 Q6 [" w! I; ~2 L
清晰的文档命名能够让我们思路非常的清晰,所以FPGA工程文件夹的目录要求层次鲜明,归类清晰。一个工程必须要有一个严整的框架结构,用来存放相关的文档、设计,不仅方便自己查看,也提高了项目的团队工作效率。# A$ V4 Y' m- i, k1 Z
7 Q  R: e, V/ A, s! p' J
下面我们来举例说明:
3 [2 h" m( K& Z2 L" [
! r/ w- o4 h1 h! N  M3 S1 J+ C4 l3 e

) w2 i! @0 s' K一级文件夹为工程名<project>
4 D) b1 ~- r% V2 `二级文件夹多个:用以存放源文件<src>用以存放Testbench文件<sim>
2 K% m* R2 `$ `用来存放设计思路相关类的文件<doc>  用来存放IP 核的文件<core>等等…

6 u8 x3 v) w3 }% Q4 U% @: L0 i7 h7 D1 f+ c. }! A
. n( c# @, U. F- X& a8 O
1 T8 q6 |5 G: {9 c
二、设计文档化:

6 h2 p# u, |8 u0 O
1 x+ l3 B* G2 O8 q4 @2 P

" W6 v6 _" S: n8 {( a4 M! u将自己对设计的思路和调试记录在文档中,有利于以后对模块功能的添加和维护,并且在项目联调时方便项目组其他人员读代码。也方便不同厂家的FPGA之间移植,以及FPGA到ASIC的移植。如下图就是设计文档化的举例说明,文档介绍清晰,功能分析明确,有利于以后对模块功能的添加和维护。: L' p! E: f! r

" p" O% c8 e0 y2 j" e; p) O/ z0 y! r
7 {5 J* z$ c9 ]& o

5 Y; r+ V4 p4 V! _# T( R( F& i
% k7 A5 V+ z' d' e% M

: ?+ h: M5 ]+ g2 o$ h3 R  r( }% l设计思路:* l' r* @  L0 k" d  G0 r

! \  c. c# V" w# j! H" Y( d

6 L; B% d4 w6 [# S; f/ S' w    按照项目的要求,自顶向下的分成若干模块,分别编写功能。顶层尽量只做行为描述,逻辑描述在底层编写。模块的编写要有硬件电路思维方式,每一个模块的设计都应考虑是否存在该硬件电路,尽量采用同步设计。5 y- f% s, R0 b4 h! a6 B% s- R. j
/ ^# l' Q1 z3 P7 I  j9 U
1 i$ @, i  [5 \) h
- M! W3 X* Q, _5 U3 z% x, R3 J& Z
三、编码风格:

7 m! R* E3 N" G3 o0 R/ n1 e: N$ @5 u$ o9 V6 `8 b1 m/ J: y

# B  n$ c& ]) d$ \: g, o# k- Q6 X) |
& j9 z; S' J* s0 d! R* g# n

- c2 m/ ~5 l. T1 z* C, [6 p% R    每个module应存在于单独的源文件中,源文件名应与其所包含的模块名相同。每个设计都应该有一个完善的文件头,包含公司名称、设计者、设计时间、文件名、所属项目、模块名称及功能、修改记录及版本信息等内容。代码中的标识符采用传统C语言的命名方法,在单词之间用下划线分开,采用有意义,能反应对象特征、作用和性质的单词命名标识符,以此来增强程序的可读性。为避免标识符过于冗长,较长的单词可以适当的缩写。& [- G/ S! o! @

* F, p' R& R+ I& n1 S& i; J/ }! t& T) G四、代码规范:

4 K/ o3 K0 m3 B4 V$ o5 C! f' O" ~5 w% r/ P

" f9 e2 V$ H8 I  I* P) P% [

! O- L; T' \. u' Q" `
低电平有效的信号,后缀名要用“_n”,比如低电平有效的复位信号“rst_n”
1 ]# j* r3 D6 i9 S! ^6 ]

模块名和信号名统一小写
5 f5 D" v) |' {6 y; T8 C4 J

变量名要小写,如wire、reg、input、output等定义的

变量命名应按照变量的功能用英文简洁表示出来“xxx_xxx_xxx”,避免过长
- {, J2 N  D/ U% F8 Y. U

采用大写字母定义常量参数,参数名小于20个字母,如parameter TIME=20. e0 [, P7 n9 y- m3 \4 z" w3 ^

时钟信号应前缀“clk”,复位信号应前缀“rst”  a/ A% b7 |9 \7 D2 K& _

对于顶层模块的输出信号尽量被寄存4 ~9 K& A) z8 ]5 G. r

三态逻辑避免在子模块使用,可以在顶层模块使用  

到其它模块的接口信号按:输入、(双向)、输出的顺序定义端口

一个模块至少要有一个输入、输出,避免书写空模块      

时钟事件的表达式用“posedge”或“negedge”的形式

If语句嵌套不能太多     

建议不要使用include语句   

建议每个模块添加timescale      

代码中给出必要的注释      

每个文件有个一头文件      

每个文件只包含一个模块      

模块名和文件名保持一致     

异步复位,用if(xxx==1’b1)  或  if(xxx==1’b0)      

同步时序逻辑的always block中有且只有一个时钟信号,并且在同一个沿动作      

采用同步设计,避免使用异步逻辑      

一般不要将时钟信号作为数据信号的输入      

不要在时钟路径上添加任何buffer      

在顶层模块中,时钟信号必须可见      

不要采用向量定义的方式定义一组时钟信号      

不要在模块内部生成时钟信号,使用pll产生      

尽量不使用任务      

不使用事件变量      

不使用系统函数      

不使用disable语句      

尽量不使用forever、repeat、while等循环语句      

不使用不可综合的运算符      

在一个always语句中有且只能有一个事件列表     

移位变量必须是一个常数      

时序逻辑语块中统一使用非阻塞型赋值      

组合逻辑语块中使用阻塞型赋值

; O* S5 }  ^! \6 f; i
五、注释规则

+ ^# m  V  L3 d$ ~- q  D
* O* q0 F/ i+ f% Q' V

7 x2 g3 c  Q0 Z9 Q! ?* I  D1、每个文件有一个文件头,文件头中注明文件名、功能描述、引用模块、设计者、设计时间、版权信息以及修改信息等;7 x9 q7 g" v6 f6 S8 }
2 k+ D. C* z% E6 |/ h

! ~! w" F1 N# d  ?2、对信号、参量、引脚、模块、函数及进程等加以说明,便于阅读与维护,如信号的作用、频率、占空比、高低电平宽度等。用“//”做小于1行的注释,用“/* */”做多于1行的注释。更新的内容要做注释,记录修改原因,修改日期和修改人。* k  I" ?" _4 X! P; [% e0 n
( u; ]! y( E; q2 q! I7 _) I. N

: r6 F5 ~+ k' k( V9 ]" J9 m1 f. b$ s7 S$ ]% `  [/ \9 R3 m7 d  [
六、模块规则

& o4 X( x, H2 k1 H2 }$ P% T/ \( C7 V, J$ K

1 \+ M" y3 N: `
* `. r& P8 k( n; v1、module例化名用u_xx_x标示;
) i1 L( R  y2 V# Q! ]6 h: k
2、建议给每个模块要加timescale;
2 C- ?  E. O# n: y) [& C3、不要书写空的模块,即:一个模块至少要有一个输入和一个输出;
2 B% N  _- m, S# _2 Z$ E, g4、为了保持代码的清晰、美观和层次感,一条语句应占用一行,每行限制在80个字符以内,如果较长(超出80个字符)则换行;
( X: a, \3 N4 X. h8 A5、采用基于名字(name_based)的调用而不是基于顺序的(order_based)的调用;
3 d+ ]# }+ A4 \& C) U  j6、模块的接口信号按输入、双向、输出顺序定义;
4 H3 u# u7 b% o" V9 d4 r. f' X7、使用降序定义向量有效位顺序,最低位为0;5 _, D/ a* F& w+ R# Z
8、管脚和信号说明部分:一个管脚和一组总线占用一行,说明要清晰;+ \5 Z) n% ?1 F4 x8 b+ ~, F* |5 n
9、不要采用向量的方式定义一组时钟信号;
$ J9 d, Y- ^+ ^10、逻辑内部不对input进行驱动,在module内不存在没有驱动源的信号,更不能在模块端口存在没有驱动的输出信号,避免在elabarate和compile时产生warning;
* ~) H4 Q- v, {, o11、在顶层模块中,除了内部的互连和module的例化外,避免在做其他逻辑;& A. \# U: |6 _2 O/ z% w' l# P; b
12、出于层次设计和同步设计的考虑,子模块输出信号建议用寄存器;9 R. s; c1 a7 `
13、内部模块端口避免inout,最好在最顶层模块处理双向总线;
8 X! b' O' ~' I; V6 ?14、子模块中禁止使用三态逻辑,可以在顶层模块使用;
4 j( w& i. D, T/ p# l7 Q15、禁止出现未连接的端口;. B! L) p% f# O. I7 ]5 ~$ o
16、为逻辑升级保留的无用端口和信号要注释;对于层次化设计的逻辑,在升级中采用增量编译;建议采用层次化设计,模块之间相对独立。
. {. o6 j1 N! d
# C& v6 T5 _7 @1 B; Z1 U& C" m

* i* w+ ^( x5 R7 b七、线网和寄存器规则
% L! t5 t) Y) Y# K* }
8 l7 [8 }6 G* |8 z1、锁存器和触发器不允许在不同的always块中赋值,造成多重驱动;
3 @; Q( ?$ E) n# G: q
2、出于功能仿真考虑,非阻塞赋值应该增加单位延时,对于寄存器类型的变量赋值时,尤其要注意这一点;阻塞赋值不允许使用单位延时;# E" H3 |0 D2 E/ q
3、always语句实现时序逻辑采用非阻塞赋值;always语句实现的组合逻辑和assign语句块中使用阻塞赋值;
2 s9 b: |  D/ V8 c( Z( V6 W4、同一信号赋值不能同时使用阻塞和非阻塞两种方式;
4 [8 q$ w) F0 ^3 r& w0 r# V1 P/ O5、不允许出现定义了parameter、wire、reg却没有使用的情况;
) h9 s3 h; |1 s1 k6、不建议使用integer类型寄存器;
2 P* E0 D6 n9 L6 W+ [7、寄存器类型的信号要初始化;
" ?! a: G2 g/ Q/ X8、除移位寄存器外,每个always语句只对一个变量赋值,尽量避免在一个always语句出现多个变量进行运算或赋值。
- p+ y2 L- Z: q6 {5 S, ]3 l6 ~% _
) U( O9 `7 r( N9 R: [5 F八、表达式规则
  i; J* P/ ]! Z  d' O# y

4 z, m- H. n' p" l1、在表达式内使用括号表示运算的优先级,一行中不能出现多个表达式;
! x0 i* n) Q' I1 z4 h/ l
2、不要给信号赋“x”态,以免x值传递;
/ e" a, [5 T- m# a5 O8 k5 W3、设计中使用到的0,1,z等常数采用基数表示法书写(即表示为1'b0,1'b1,1'bz或十六进制);
5 H3 ?1 T. \; N' Q0 @4、端口申明、比较、赋值等操作时,数据位宽要匹配。7 s$ J3 t, r' [, l: F) H

  W+ ^2 d5 o) U4 k+ p2 O2 ^" @
: `$ Q* p4 B7 `/ ^3 r) A

1 y$ X6 @: j% i9 e) U, h九、条件语句规则
6 }3 C  J1 a' V. w
( h/ A$ E5 B& x  V

( G% L! Q; y+ H1、if 都有else和它对应,变量在if-else或case语句中所有变量在所有分支中都赋值;0 ~  a6 _/ I1 `1 n3 J% o0 T& w8 T7 ^
2、如果用到case语句,记得default项;
1 r5 F! y9 L+ i2 q, T6 l# _( }5 D3、禁止使用casex,case语句item必须使用常数;9 v5 i( ^- `2 c  ?* N3 V
4、不允许使用常数作为if语句的条件表达式;4 N+ k& h8 {" j3 _' B2 G6 [. u* R( b
5、条件表达式必须是1bit value;5 Y& E) I) m; |' ^7 k6 Q
6、如异步复位:高电平有效使用“if(asynch_reset==1'b1)”,低电平“if(asynch_reset==1'b0)”,不要写成:“if(!asynch_reset)”或者“if(asynch_reset==0)”;
, B4 l) J3 h1 u8 W0 Y) M; ?3 i7 t: W7、不推荐嵌套使用5级以上if…else if…结构。. w$ q* [9 n5 {/ T( s9 O3 c

) H$ _, ~3 b: J5 s8 ?! l& p0 h十、可综合部分规则

2 n2 I' c  h+ k( Y  ~8 n' ~) l+ k
% H  u# d$ `- Q) y; j& ~

4 ~5 d) k" u0 S) F$ W1、不要使用include语句;
- h! W, n. U! i8 k7 i0 T$ L- ]2、不要使用disable、initial等综合工具不支持的电路,而应采用复位方式进行初始化,但在testbench电路中可以使用;9 h2 n) M6 @5 b, x# _5 Y- |9 A- @
3、不使用specify模块,不使用===、!==等不可综合的操作符;9 P# h* e. ^. ]5 X
4、除仿真外,不使用fork-join语句;
, p: W7 T3 N3 u( f' i: v. N5、除仿真外,不使用while语句;5 X  S' Z! o; A7 J& P
6、除仿真外,不使用repeat语句;& l& @4 Z; _# V. L0 ]9 L2 {
7、除仿真外,不使用forever语句;
$ s$ v  k. b3 M/ m( i5 S8、除仿真外,不使用系统任务($);2 d0 ^* w# G3 j& d
9、除仿真外,不使用deassign语句;: Q: p" r+ ~3 S# w% A
10、除仿真外,不使用force,release语句;% B8 l7 l4 T7 e  j. ~% }! G! t
11、除仿真外,不使用named events语句;不在连续赋值语句中引入驱动强度和延时;
5 u2 X9 V8 j+ c( P3 `- S12、禁止使用trireg型线网;* \% H- K- }1 ~! ^* t) F
13、制止使用tri1、tri0、triand和trior型的连接;. t, H5 g4 a1 D+ U/ J9 ~( s* K. f
14、不要给驱动supply0和supply1型的线网赋值;, X2 q- j  F: v
15、设计中不使用macro_module;
; n1 F- f( m" \8 i! L16、不要在RTL代码中实例化门级单元,其下列单元:(CMOS/RCOMS/NMOS/PMOS/RNMOS/RPMOS/trans/rtrans/tranif0/tranif1/rtranif0/tranif1/pull_gate)。
! i2 h6 k. w: o7 s; i3 d" ^$ I. ^0 Y3 |

* p3 f0 ~0 T/ Q$ z) S. A, a' m! `6 {  P: o$ s% C, T" m  S9 o7 M
十一、可重用部分规则

+ F$ ~- M1 ~9 }' [* _
- @) G$ a# g* Z) N; ^
' I8 |) X' Q% B/ S  R0 d7 n
1、考虑未使用的输入信号power_down,避免传入不稳定态;
' m$ A/ p5 `# i0 m1 j( G: T; ]2、接口信号尽量少,接口时序尽量简单;
# u6 Q2 q: ~, @- O* H3、将状态机(FSM)电路与其它电路分开,便于综合和后端约束;
3 q. C  A! L% U: L7 I1 u0 ~4、将异步电路和同步电路区分开,便于综合和后端约束,将相关的逻辑放在一个模块内;. y) Q5 `$ g8 I( ^3 [1 x
5、合理划分设计的功能模块,保证模块功能的独立性;
8 I- ]6 G$ L3 l" h  B( h& [- l# _6、合理划分模块的大小,避免模块过大;
0 ]) A) k& H" n7、在设计的顶层(top)模块,将I/O口、Boundary scan电路、以及设计逻辑(corelogic)区分开。' m1 S7 w/ `# R* S* F

, D" x+ u, ~! l) c6 E3 g/ `十二、同步设计规则
$ c2 d1 X9 d# D7 y& G0 T
3 L# z" D4 W8 [% R2 M
3 T3 s# G7 [. h. m
1、同一个module中,要在时钟信号的同一个沿动作;
* o5 ]; C& X$ t, {2、如果必须使用时钟上升沿和时钟下降沿,则要分两个module设计;
) u0 ~" y) p* ~4 m% F& I2 B3、在顶层模块中,时钟信号必须可见,不在模块内部生成时钟信号,而要使用DCM/PLL产生的时钟信号;5 X% w5 u( K/ K1 U
4、避免使用门控时钟和门控复位;4 N# F, W, T' D6 l
5、同步复位电路,建议在同一时钟域使用单一的全局同步复位电路;异步复位电路,建议使用单一的全局异步复位电路;
" N& q7 T5 ]6 E, M) O: v1 X6、不在时钟路径上添加任何buffer;) j! z: G( P9 m& u  f3 S# x1 r
7、不在复位路径上添加任何buffer;. k0 W- |8 s8 @4 n# ]. G& H% {
8、避免使用latch;: L. _8 ^9 w) J+ h' D- T; l% F
9、寄存器的异步复位和异步置位信号不能同时有效;1 X) E: H1 R  A5 O6 y! z+ a1 T
10、避免使用组合反馈电路;
0 M0 O2 K% ^( `8 ~1 O11、always有且仅有一个的敏感事件列表,敏感事件列表要完整,否则可能会造成前后仿真的结果不一致;
) M! j% [$ T4 Y0 S12、异步复位情况下需要异步复位信号和时钟沿做敏感量,同步复位情况下只需要时钟沿做敏感量;
$ l. u& I& ]! H; K# D13、时钟事件的表达式要用:“negedge<clk_name>”或“posedge<clock_name>”的形式;
/ {- h/ l) j: h4 z14、复杂电路将组合逻辑和时序逻辑电路分成独立的always描述。- z" f; |7 P! @# z  H4 E

2 j0 R* G6 j6 f( g8 }( [2 ]
6 C4 A- R( _" f$ g  Y* M+ N
# z& |: P7 @2 ]4 C$ g2 `( J
十三、循环语句规则
; h5 p( V8 {* E( k' J1 n

8 G0 V, o2 P  P* _- m. J

9 E- N* K# ^# |1、在设计中不推荐使用循环语句;2 `$ G5 G% |+ ?8 @  }( P& r7 m" S
2、在非常有必要使用的循环语句时,可以使用for语句。
6 W  z, @' k9 v- \" a4 t
; {0 l# F9 R" \, U/ V# Z# w十四、约束规则
) b; j, j+ h! J% }7 l

: Y+ c& U9 `* c0 {7 S
4 Q* f! R2 O+ d+ f0 U
1、对所有时钟频率和占空比都进行约束;
) c. J2 {9 p$ i) t2、对全局时钟skew进行约束;
2 I, g2 |  l# y) v+ I# N3、对于时序要求的路径需要针对特殊要求进行约束,如锁相环鉴相信号;
, u9 a) z( T& K  U# a! E" J4、要根据输出管脚驱动要求进行约束,包括驱动电流和信号边沿特性;$ ~- U, [/ s  e, T* ?! @, p. T
5、要根据输入和输出信号的特性进行管脚上下拉约束;
: E) l" p; h- e3 N6、针对关键I/O是否约束了输入信号和输入时钟的相位关系,控制输入信号在CLK信号之后或之前多少ns到达输入pad;
. l! e2 ~# i* O) ?  M4 C+ z8 h7、综合设置时,fanout建议设置为3030;; y& c% K- F8 a1 N: G. t8 a
8、要使用输入输出模块中的寄存器,如Xinlinx公司的IOB,map properties选项pack I/O register/latches into IOBsactor需要设置成为“for input and output”,这样可以控制管脚到内部触发器的延时时间;
) n- O/ J0 D) {2 B# q% V9、布局布线报告中IOB、LUTs、RAM等资源利用率应小于百分之八十;
5 l/ N3 _1 f5 ^10、对于逻辑芯片对外输入接口,进行tsu/th约束;对于逻辑芯片对外输出接口,进行约束。
# |; m0 s) H5 e7 P7 r& i
% d) X9 q6 a, X5 j+ ]! R十五、PLL/DCM
; L8 O% N$ t% t

0 s7 r  X* A" b$ {8 u1、如果使用FPGA内部DCM和PLL时,应该保证输入时钟的抖动小于300ps,防止DCM/PLL失锁;如果输入时钟瞬断后必须复位PLL/DCM。
: t+ b1 H# V7 Z* O: ?  B
2、对于所有厂家的FPGA,其片内锁相环只能使用同频率的时钟信号进行锁相,如果特殊情况下需要使用不同频率的信号进行锁相,需要得到厂家的认可,以避免出时钟。+ `  e- D7 ]( _. P" N- j, r. Q  R

1 x7 }1 c. G1 t7 w, `2 w十六、代码编辑由于不同编辑器处理不同,对齐代码使用空格,而不是tab键。
+ i' B9 y) Z1 [6 f" m/ X# \

0 N+ L" N6 _6 B" _4 {( B0 X4 f! x% V***可综合和不可综合详解***

2 t2 e0 l6 g# U$ l! ]8 R(1)所有综合工具都支持的结构:always,assign,begin,end,case,wire,tri,aupply0,supply1,reg,integer,default,for,function,and,nand,or,nor,xor,xnor,buf,not,        bufif0,bufif1,notif0,notif1,if,inout,input,instantitation,module,negedge,posedge,operators,output,parameter。
9 b4 F6 E- h; l% a/ R2 D(2)所有综合工具都不支持的结构:time,defparam,$finish,fork,join,initial,delays,UDP,wait。(3)有些工具支持有些工具不支持的结构:casex,casez,wand,triand,wor,trior,real,disable,forever,arrays,memories,repeat,task,while。
; b; E. I" p' M8 ^4 @3 t1 C4 S- j- m, Z5 g, `6 ^+ G
建立可综合模型的原则& C4 |2 S) U# ^+ m- T9 t2 E" N
要保证Verilog HDL赋值语句的可综合性,在建模时应注意以下要点:

" A. ^, U' `  I- H* f, O6 H! q6 `% s
(1)不使用initial。

4 y% R2 ?- e+ ?(2)不使用#10。   
0 M3 h5 p! Z" `8 a+ D. ?( q7 a1 V(3)不使用循环次数不确定的循环语句,如forever、while等。  $ \& j/ D4 P- _$ A/ z9 @
(4)不使用用户自定义原语(UDP元件)。   0 W; @+ {' w* C3 V
(5)尽量使用同步方式设计电路。
3 V8 k1 ~# X9 ?0 q(6)除非是关键路径的设计,一般不采用调用门级元件来描述设计的方法,建议采用行为语句来完成设计。  
: k4 E9 {. H. S, [, o1 {(7)用always过程块描述组合逻辑,应在敏感信号列表中列出所有的输入信号。   ( f) A, _. j9 e) a1 m1 _$ ]/ D# q" Z
(8)所有的内部寄存器都应该能够被复位,在使用FPGA实现设计时,应尽量使用器件的全局复位端作为系统总的复位。   4 b) O; E9 g" _
(9)对时序逻辑描述和建模,应尽量使用非阻塞赋值方式。对组合逻辑描述和建模,既可以用阻塞赋值,也可以用非阻塞赋值。但在同一个过程块中,最好不要同时用阻塞赋值和非阻塞赋值。   
8 ]# ], O) V+ c(10)不能在一个以上的always过程块中对同一个变量赋值。而对同一个赋值对象不能既使用阻塞式赋值,又使用非阻塞式赋值。  ( O9 w$ b. Y7 D# J" V
(11)如果不打算把变量推导成锁存器,那么必须在if语句或case语句的所有条件分支中都对变量明确地赋值。 (12)避免混合使用上升沿和下降沿触发的触发器。   % P8 W8 R7 u: J9 }
(13)同一个变量的赋值不能受多个时钟控制,也不能受两种不同的时钟条件(或者不同的时钟沿)控制。  3 d1 \6 z* e# f1 ^5 [: X
(14)避免在case语句的分支项中使用x值或z值。
- a2 z; g9 Y! |) u. p, T) p  {8 a2 C* ^
1、initial 只能在test bench中使用,不能综合。(用ISE9.1综合时,有的简单的initial也可以综合,不知道为什么)   
, I. K+ x* G2 q* F! U7 z
2、events
8 L" H0 |: H0 T' F5 J# K' Y! devent在同步test bench时更有用,不能综合。
7 B+ q5 J/ k. ]) i, n. j3、real3 H  h- A* F& |; s# \/ V" U& Q* o
不支持real数据类型的综合。, h# \5 U8 z. a& N! m' Y. P5 e
4、time                           / F1 r2 v0 W( A+ j+ L7 F. [
不支持time数据类型的综合。5 Q4 n8 Y7 X$ z4 l
5、force 和release      # A' m& U, M* `5 q5 ^8 N- a- R9 M
不支持force和release的综合。
4 M7 i: ~$ w' R, t* q9 C6、assign 和deassign      / {! y# [/ P- H. `
不支持对reg 数据类型的assign或deassign进行综合,支持对wire数据类型的assign或deassign进行综合。

. e2 n' @" q4 E1 V& I, m+ O2 n+ q& ?7、fork join                     7 C) I( j( d2 A+ ^
不可综合,可以使用非块语句达到同样的效果。      
, ^& C3 }7 [: A! Q8、primitives               
4 T' q  w+ i9 V& I支持门级原语的综合,不支持非门级原语的综合。5 T! \/ j  `; s- U
9、table                    
# g- A) x3 D, f; C! M  t9 G$ [3 i不支持UDP 和table的综合。
) N$ ]9 @; H" Z9 h  e0 {2 i2 t10、敏感列表里同时带有posedge和negedge& V' n, D% Q/ L7 T1 m% e3 m6 R
如:always @(posedge clk or negedge clk) begin...end这个always块不可综合。; Z6 u9 t, n: c
11、同一个reg变量被多个always块驱动
7 U- m$ i) f1 Y12、延时
* W, N) Q; _+ n+ e以#开头的延时不可综合成硬件电路延时,综合工具会忽略所有延时代码,但不会报错。5 H# }8 R2 b1 g& g
如:a=#10 b;这里的#10是用于仿真时的延时,在综合的时候综合工具会忽略它。也就是说,在综合的时候上式等同于a=b;
# {$ j0 a1 w. b. y+ w7 n- V13、与X、Z的比较
1 U- {! K# m7 g# G6 A可能会有人喜欢在条件表达式中把数据和X(或Z)进行比较,殊不知这是不可综合的,综合工具同样会忽略。所以要确保信号只有两个状态:0或1。如:
3 ?/ a3 F5 r( M3 T) H. [

. x' d3 D1 O) b" \, M
. h7 G# P( o4 J以上是个人整理出来的一些设计规范,有些部分有重复,但无伤大雅,适用于FPGA Verilog HDL设计,VHDL的话设计思想是一样,大同小异,大家可以举一反三。[tr]后续会持续更新,带来Vivado、 ISE、Quartus II 、candence等安装相关设计教程,学习资源、项目资源、好文推荐等,希望大侠持续关注。[tr]大侠们,江湖偌大,继续闯荡,愿一切安好,有缘再见!; F" g) n7 U: r: G0 A% z3 N

* Y3 D, T$ ^* `4 Q! x# @# j& v7 W5 b

该用户从未签到

2#
发表于 2023-5-23 18:23 | 只看该作者
说的再多还的从语言,语法开始
  • TA的每日心情
    开心
    2024-5-11 15:34
  • 签到天数: 110 天

    [LV.6]常住居民II

    3#
    发表于 2023-5-26 10:49 | 只看该作者
    6、如异步复位:高电平有效使用“if(asynch_reset==1'b1)”,低电平“if(asynch_reset==1'b0)”,不要写成:“if(!asynch_reset)”或者“if(asynch_reset==0)”;
    $ G$ S; {3 `' q6 {! C5 b请问这个是为什么,有啥说法?
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    关闭

    推荐内容上一条 /1 下一条

    EDA365公众号

    关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

    GMT+8, 2025-10-28 18:42 , Processed in 0.203125 second(s), 26 queries , Gzip On.

    深圳市墨知创新科技有限公司

    地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

    快速回复 返回顶部 返回列表