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

FPGA经典设计案例1

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2019-3-20 15:56 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

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

x
FPGA经典设计案例1
* u+ n% S+ Z0 ~/ w% u0 z+ R

  ]" s# H* U, e6 N# k: n3 N5 T
学习FPGA,最关键的是学什么?有读者学了大半年时间的FPGA,学了串口就只懂串口的设计,学了spi就只懂SPI接口的设计。每个接口、每个功能,都只是学一个懂一个。换个功能需求,或者对接口做一个小小的改动,就无从下手了。
设计代码,从来都只是模仿,或者不断地调试修改,凑代码。设计出的代码也没有任何规律,相同的功能,今天设计和明天设计都不一样。这就如学功夫,今天学下少林,明天学下武当,后天又学下华山,在这样的情况下,能成长为高手,那就奇怪了。
在明德扬看来,FPGA设计应该有一套通用的设计方法。该方法能够应付所有的功能设计,无论功能怎么变,都可以用该方法来套用。明德扬发明的这套方法就是至简设计法。
至简设计法从宏观上,适应所有的功能设计需求。例如,无论是什么功能,我们都先将其转化成需求波形。然后在此基础上设计模块架构;在模块架构基础上设计信号。这步骤都是通用的、是固化的。
至简设计法在微观上,则制定得实用的规范。详细到,要不要添加信号;怎么添加信号;添加信号的名字规范等,我们都做了详细的规定。
下面我们用4个经典例子,讲述了至简设计法的使用技巧。其他复杂功能,无论怎么变,都是这4个经典案例的变种。读者只需要强化、巩固技巧,多训练,多应用,逐步成长为高手。
至简设计法经典案例1
案例1. 当收到en=1后,dout产生一个宽度为10个时钟周期的高电平脉冲。

4 Q" z5 j# G* Y
需要说明,根据看波形规则,在第3个时钟上沿的时候,看到en==1,根据功能要求,上升沿之后dout就会变为110个时钟周期后,dout将变为0
从功能要求中,看到数字10,我们就知道要计数,并且是dout==1的次数为10个。所以我们计算的是dout==1的时钟次数,并且是10次。为此,补充一个计数器信号cnt,更新后的波形如下图。
计数器cnt要遵守如下原则。
初值一定为0。
除了最后一个,在时钟上升沿,看到dout==1,就将cnt值加1
在时钟上升沿时看到dout==1,并且是最后一个时,cnt值不加1,直接清零。
从功能要求和波形图,我们确认,计数器cnt是对dout==1进行计数,并且一共数10个。为此,在GVIM编辑器中输入“Jsq”并回车,将出现如下代码。
在第13行,输入dout==1,在第14行代码中,输入10-1,这样就完成了计数器设计。
代码解释:第1至第11行,是一个时序always的代码。该代码要描述的功能是:
在时钟clk上升沿或者复位rst_n的下降沿的时候,always就对cnt判断条件并变化一次。具体变化过程如下:
如果是rst_n==0,则将cnt变为0。
否则(即rst_n==1),如果add_cnt有效,也就是为1的时候。继续判断条件并执行。
如果end_cnt有效,即end_cnt==1,则将cnt变为0。
否则(即end_cnt==0),cnt就自加1。
否则(即rst_n==1且add_cnt==0的时钟),cnt保持不变。
上面代码中add_cnt表示计数器加1条件,end_cnt表示计数器数到最后一个。
上面代码描述过于复杂,其实概括起来,功能就是:时钟上升沿时,如果计数器加1条件有效,并且是数到最后一个,则计数器清零;如果计数器加1条件有效,但不是最后一个,则计数器就加1;其他时候,计数器就保持不变。
那么加1条件,即add_cnt是什么呢?在第13行进行了定义。该行代码表示,dout==1就是计数器的加1条件。
那么结束条件,即end_cnt是什么呢?在第14行进行了定义。该行代码表示,数到10个就结束。其中我们关注的是那个数字10,而-1是固定的格式。
add_cnt && cnt==10-1,含义是表示“数到第10个的时候”,add_cnt &&cnt==x-1表示“数到第x个的时候”。记住这个规则。end_cnt==1也表示数完了。
设计好计数器cnt后,我们就可以设计输出信号dout了。仔细分析dout,该信号有两个变化点:变1和变0。我们分析原因,dout1是由于收到en==1dout0,则是数到了10个或者是数完了。所以综上所述,dout的代码是:
至此,我们完成了主体程序的设计,接下来补充module的其他部分。
module的名称定义为my_ex1。并且我们已经知道该模块有4个信号:clkrst_nendout。为此,代码如下:
其中clkrst_nen是输入信号,dout是输出信号,并且4个信号都是1比特的,根据这些信息,我们补充输入输出端口定义。代码如下:
接下来定义信号类型。
cnt是用always产生的信号,因此类型为regcnt计数的最大值为9,需要用4根线表示,即位宽是4位。add_cntend_cnt都是用assign方式设计的,因此类型为wire。并且其值是0或者11个线表示即可。因此代码如下:
dout是用always方式设计的,因此类型为reg。并且其值是0或者11根线表示即可。因此代码如下:
至此,整个代码的设计工作已经完成。整体代码如下:
1

& k; U, L/ M" c1 X9 M
2
$ N9 _1 `# |) b# O" Q  |
3

- s& n3 d1 a% }1 i* q
4
) J+ `3 b7 |9 x' i1 z( H
5

' p  a$ k& T& H( i0 B" a1 P0 M7 `
6
) W# l6 t% s8 w
7

! J% {4 |2 o$ B7 [+ n
8
7 u% y6 B5 U5 d: o: P. W. n% \
9

, a) U; r8 ]$ ~& O  Z9 q! T7 H
10
- z7 w& ]/ W- c. [
11

- V" I  `+ l1 w: X8 g
12

/ D4 b/ A: [( E
13

  w# d4 T$ e6 L5 x" o6 \
14

7 S, Z, J4 ]* l5 a: o- s) @6 P
15
! e6 V+ t- x/ h  a6 w9 Z$ P. ~! V& D
16
& N3 L- n: g1 t! a1 v5 {: r
17

7 j. q  N8 a+ X% |, c2 f7 A; r
18

* _2 X& t8 ]4 T$ K8 o! l7 c
19

$ D  }( g3 W2 A* p
20

' U! Z8 z! k1 t2 ^
21
! c+ I8 s: n1 E( L' l+ h& f
22
2 ~# k# }! s/ m: R; f6 f; S: @, q
23

* i9 t) s! J' c* |7 `8 N/ i
24

- M  x% [6 K) D1 Y" @
25

2 U( c6 P0 }1 c% r7 S7 T4 c, v
26
' G; C7 H3 w( u/ {
27
" I$ k: ?! K  U9 u% A3 u" b# w
28
module my_ex1(

  v' R7 X' Q% H  r! u
      clk      ,

9 q- N% L4 Y6 K2 ]0 \, }  m. s  {( E
      rst_n    ,

- c7 k* q" e6 v$ N' m
      en       ,

  u5 L! M1 _$ m" `2 j
      dout        

; M4 ~7 U# ]+ Z$ _+ v% l
);
3 d* D3 p; n3 r7 |5 y5 M' |3 i+ |
input     clk     ;

9 R2 ]6 X4 A* b% c; s) I" z! M4 L
input     rst_n   ;

5 v$ @, W& v+ A& S0 l3 Z! y6 @5 W
input     en      ;

8 P* j, P" y& U1 `( S! @/ i
output    dout    ;
7 @/ ]+ l4 Q. G1 T( _
reg [ 3:0]  cnt      ;
) {: I; B; o' r4 ]0 q
wire        add_cnt ;
" d& K7 @: Z. X% k! F" F
wire        end_cnt ;

, K6 Q  a( D* A: \2 M/ B
reg         dout    ;
+ `/ R1 c$ l# J! I6 [, s; \
always @(posEDGE clk or negedge  rst_n)begin

4 W" r& J8 L2 J  s. C! Y2 D
     if(!rst_n)begin

- d1 R$ f6 C) f: j) {4 F4 q, y  [
         cnt <= 0;
6 \5 s0 |4 ]2 z
     end
1 h2 {; s9 ?# e4 M0 a! q
     else if(add_cnt)begin

2 p' x) G$ s( S! C+ X4 X8 d
         if(end_cnt)
; ~& [. G- K1 r" Z
            cnt <= 0;

! w9 e. T/ `2 I0 K9 \$ ~
         else
" L6 i: g8 g6 C; g- m& e
            cnt <= cnt + 1;
4 C( z6 ?5 [" @* p+ [" p
     end

7 m0 p, c1 d* v1 K4 y) M
end

! s$ O% r' J' q' p9 X
assign add_cnt = (dout==1);      

1 L" Q6 j4 d- J$ s1 {
assign end_cnt = add_cnt &&  cnt==10 -1 ;   

' k5 `  z1 [; }! p5 ]; h
always   @(posedge clk or negedge rst_n)begin

" `2 }3 T- p; a8 A: i: ]5 W$ j' c
     if(rst_n==1'b0)begin

# M+ {* z; V+ s# s& Z9 m8 d3 d1 \$ z) l
         dout <= 0;

3 o* F7 B* {, b8 z
     end

8 q$ s' K) k# y. ?: C* T$ s" y5 a
     else if(en==1)begin

9 [" `, z$ K8 t1 f/ H: X
         dout <= 1;

( f2 l8 y- X# g
     end
. I! W2 Y9 o+ o2 G) N6 [+ Q
     else if(add_cnt && cnt==10-1)begin

# g4 V9 j& R1 V4 [; f  Z1 T
         dout <= 0;

) ]( N. ?% N' I
     end

- ^- l# z2 F! n# y& B0 B) ?9 m, U9 ~8 ~& ?
end
/ ]1 c$ F( O9 U; `6 J- k& r1 ]
endmodule
3 A4 D1 y: }7 |/ \' V* U

) [6 u9 n% e$ F, ~0 a5 e0 h+ ~
, e+ R" Y1 s# N* g, f7 s' ~" I& V! ?/ l3 H8 E

该用户从未签到

2#
发表于 2019-4-4 16:40 | 只看该作者
谢谢楼主的整理 费心了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-7-30 14:50 , Processed in 0.125000 second(s), 23 queries , Gzip On.

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

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

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