|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
本帖最后由 明德扬FPGA科教 于 2020-2-29 16:19 编辑 ! {) R) V" c) X6 S7 s' ~% g
& e7 a/ n2 i/ i* Q/ m2 s9 ~
关于锁存器问题的讨论+ g/ G: @: t+ g: z) y1 }
- J# m! \7 _. c2 A# r5 |! w
' y" h( Q. ]0 a/ F, a- ~- V上面是两个没有else 的代码,其等效于下面的代码。& C1 }, R- H0 j" ^( U
& t! T+ V1 C9 y# h* D n! F
+ T2 k7 P3 V x: M9 R
也就是说,当if 条件里面没有写else 时,默认是表示“保持不变”的意思。
?7 E" s: ]$ j/ j1 c. e7 {' {8 B
) v$ E# C* o9 h2 L
$ d% g" G: J: w" G' J: H! K接下来,我们来讨论一下,硬件中是如何实现“保持不变”的。
3 l; v) d1 c! t2 C* ~
: A& Z8 ^* u3 K; R" |+ w) u
0 m% r/ B0 w* E. e
5 d# d# K0 D( J左边是时序时序逻辑的代码,右边是该代码所对应的硬件电路。特别注意图中红色的那个线,那个就是保持不变的“反馈”。由图中可以看出,当时钟上升沿的时候,当选择器的结果赋值给信号b ;非上升沿的时候,b 一直保持不变,因此红色线在此期间也是保持不变的。当a 为0 的时候,选择器选择当前b 的结果,然后在下一个时钟上升沿赋给信号b 。
9 l6 f2 e8 W% \7 ]6 \* z# P& N3 _+ Y% [由引可见,实现“保持不变”的关键在于D 寄存器。
# s# G9 E8 ]. U 4 y4 \# }1 d! i
众所周知,组合逻辑代码是没有D 寄存器的,那么它又是如何实现保持不变呢?这个就会用到锁存器了。9 v" ]5 l2 d9 E
. k0 n2 E# G6 t7 k. A
7 y {$ V5 h9 ^# g4 B5 c" R" e9 Q
1 J: Y4 ]; B$ L% M7 ?/ \0 E- s U, p上图左边是组合逻辑代码,右边是其电路。为了让信号b 保持不变,就要用到一个叫“锁存器”的器件。当a 为1 时,b 就会等于1 ;当a 为0 时,b 会保持不变。
* s) q; U3 z6 M0 ~- \1 ]关于锁存器的危害,可以参考MDY 的“大串讲”视频,总之我们知道锁存器是不好东西的,尽量不要有锁存器,也就是说组合逻辑里,要让“if else ”条件补全。$ g4 j6 u1 C9 d9 ]! v9 g9 L
3 i5 K. ~ F8 ^0 |) m, x' d7 w
常见问题
+ d$ o, f F& H3 k/ u问1 :是不是所有的代码,if else 都需要补全呢?1 @( j3 j" r$ V# P% ]
答:如前面所讨论的,对于时序逻辑可以由D 寄存器实现“保持不变”,所以时序逻辑是不需要补全的,只有组合逻辑才需要。5 Y" i2 P! G6 n/ w' g
2 s T6 r6 }! M) K( d+ a' e问2 :是不是只要组合逻辑的if else 补充了,就不会生成锁存器了?: i% b$ Y7 d* n4 k# F+ W) k" u
答:不一定。这里的关键在于“保持不变”,千万不要从“代码层次”来理解,而应该从“功能的层次”来理解,要找准到底有没有“保持不变”。例如,下面的代码,虽然else 写上去了,但写不写else 都是让b 保持不变。所以这仍然会综合出锁存器。
% y# D! C# e% w - e% v8 O( Y2 b# l) ~( E6 @
, ?+ _$ }7 o% y
问3 :是不是组合逻辑不写else ,就一定会生成锁存器?
7 j2 V6 d" ^1 i9 C2 f答:不一定。这里仍然要从是否包括“保持不变”这个功能来分析。如下面代码,假设a 是1 比特信号,其值只有0 和1 。那么已经涵盖了所有情况,再不会有其他情况,所以不会出现保持不变的情形,这个时候也不会生成锁存器。; n" A# K; O+ w, G M8 o% s
; c {7 S( g; h T
/ U& l" a ~8 m# u K问4 :case 不写default ,是否会生成锁存器?5 r7 _+ K/ P1 \1 s
答:case 不写default ,相当于if 条件不写else ,其情况分析跟前面3 个问题一样,关键在于有没有“保持不变”的功能。
! }6 _& O) h8 L
, K" p# w, k' G/ h. v问5 :功能上,我一定要实现“组合逻辑的保持不变”功能,该如何做?
+ }; G6 ~. P7 Y; e( j- g答:通常来说,所谓“组合逻辑的保持不变”,是指“该段代码”是组合逻辑写的,但需要与前一个时钟的值保持不变,如下代码,这种需求是很正常的。
. d9 e- z& _! E4 g0 j 5 x# S8 X! T. k$ k, |; ~
$ Z$ g1 e2 P7 s( Y! A- G解决方法,仍然是靠D 触发器来实现“保持不变”的功能。只不过是把一个时序逻辑的ALWAYS 写法,换成组合逻辑+ 时钟逻辑的写法而已,代码如下。7 j! E( E) U5 [9 y
8 A$ K. _( z1 z) R$ k8 [
+ y" p8 W. l0 J) c- W& }; G
问6 :问题5 的扩展,我就是要实现组合逻辑的保持,并且小于一个时钟周期的。$ H8 x. U" [# T( a' N2 ?4 G: o
答:不正常需求,FPGA 不会这么设计的。
, n# u" m; F3 ] # R1 r7 y e6 t9 C; i9 D" t
T' Z) U0 |+ A3 ]' R1 k/ ~, g/ G+ @ Z
! X. {5 R- m, g; @
' D$ S" l3 T# P2 ?" [9 p - R% w& \. T% \$ J
. {0 W4 q+ L8 B- p# ~! D |
|