2190|3

22

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

FPGA经典设计案例 [复制链接]




此内容由EEWORLD论坛网友mdy-吴伟杰原创,如需转载或用于商业用途需征得作者同意并注明出处

 

至简设计法经典案例

学习FPGA,最关键的是学什么?有读者学了大半年时间的FPGA,学了串口就只懂串口的设计,学了SPI就只懂SPI接口的设计。每个接口、每个功能,都只是学一个懂一个。换个功能需求,或者对接口做一个小小的改动,就无从下手了。

设计代码,从来都只是模仿,或者不断地调试修改,凑代码。设计出的代码也没有任何规律,相同的功能,今天设计和明天设计都不一样。这就如学功夫,今天学下少林,明天学下武当,后天又学下华山,在这样的情况下,能成长为高手,那就奇怪了。

在明德扬看来,FPGA设计应该有一套通用的设计方法。该方法能够应付所有的功能设计,无论功能怎么变,都可以用该方法来套用。明德扬发明的这套方法就是至简设计法。

至简设计法从宏观上,适应所有的功能设计需求。例如,无论是什么功能,我们都先将其转化成需求波形。然后在此基础上设计模块架构;在模块架构基础上设计信号。这步骤都是通用的、是固化的。

至简设计法在微观上,则制定得实用的规范。详细到,要不要添加信号;怎么添加信号;添加信号的名字规范等,我们都做了详细的规定。

下面我们用4个经典例子,讲述了至简设计法的使用技巧。其他复杂功能,无论怎么变,都是这4个经典案例的变种。读者只需要强化、巩固技巧,多训练,多应用,逐步成长为高手。

至简设计法经典案例1

案例1. 当收到en=1后,dout产生一个宽度为10个时钟周期的高电平脉冲。

 

需要说明,根据看波形规则,在第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==1add_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

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

module my_ex1(

     clk      ,

     rst_n    ,

     en       ,

     dout       

);

input    clk     ;

input    rst_n   ;

input    en      ;

output   dout    ;

 

reg [ 3:0]  cnt     ;

wire        add_cnt ;

wire        end_cnt ;

reg         dout    ;

 

 

always @(posedge clk or negedge rst_n)begin

    if(!rst_n)begin

        cnt <= 0;

    end

    else if(add_cnt)begin

        if(end_cnt)

            cnt <= 0;

        else

            cnt <= cnt + 1;

    end

end

 

assign add_cnt = (dout==1);      

assign end_cnt = add_cnt && cnt==10 -1 ;  

 

always  @(posedge clk or negedge rst_n)begin

    if(rst_n==1'b0)begin

        dout <= 0;

    end

    else if(en==1)begin

        dout <= 1;

    end

    else if(add_cnt && cnt==10-1)begin

        dout <= 0;

    end

end

 

endmodule

  如果你觉得有用的话,就请你回个贴或者赞,证明我的付出没有白费,大家都不容易,q328908175,让我们共同学习。

此帖出自FPGA/CPLD论坛

最新回复

加油!   详情 回复 发表于 2019-8-19 09:02
点赞 关注
 

回复
举报

2

帖子

6

TA的资源

一粒金砂(初级)

沙发
 

没有白费,很好。感谢。

此帖出自FPGA/CPLD论坛
 
 

回复

3

帖子

0

TA的资源

一粒金砂(初级)

板凳
 

显示不出图片   是我浏览器的问题吗

 

此帖出自FPGA/CPLD论坛
 
 
 

回复

2

帖子

0

TA的资源

一粒金砂(初级)

4
 

加油!

此帖出自FPGA/CPLD论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表