[资料] 基于至简设计法的数字时钟设计

[复制链接]

技术员

发表于 2017-2-15 17:32:23   364 查看 1 回复 显示全部楼层 倒序浏览
分享
基于至简设计法的数字时钟设计
明德扬科技教育有限公司
官  网:www.mdy-edu.com
淘  宝:mdy-edu.taobao.com
QQ 群:97925396

数字时钟是常见的毕业设计题目。我们做毕业设计时,一般使用数码管来显示数字。小时、分钟和秒钟各两位数字,所以需要用到6位的数码管。
如果平时不动手,要做这个毕业设计,很多人都会觉得挺难的。收集到的代码,其风格也是五花八门,第一感觉是貌似能看懂,但就是不知道怎么设计出来的。
其实如果有正确的设计思路和方法,其实现起来是非常简单的。下面我们就核心的数字模块为例,讲解如何使用至简设计法来实现。
数字模块的功能,是产生6个信号,分别表示时十位、时个位、分十位、分个位、秒十位和秒个位的值。例如上述信号值依次为2、1、4、3、5、9时,则表示时间为21点43分59秒。
仔细观察6个信号,每个单独来看,其数字都是递增的,增加到一定数后就清零。以秒个位为例,开始时值为0,然后是1、2、3依次增加,直到变成9后,然后变成0,再次循环。其他信号都是相同的规律。这些依次递增的信号,就是计数器。
我们认识到这些信号是计数器,那就好办了,明德扬最擅长就是计数器的设计。计数器设计只需要考虑两点,什么时候加1和要数多少个,明确这两个问题后,剩下的就是套用明德扬计数器模板了。
以秒个位这个计数器为例,这个计数器加1的条件是什么呢?到了1秒就加1。那我们怎么知道1秒钟时间到了呢?FPGA是通过数时钟周期数来确定时间的。例如下图,假设时钟频率是50MHz,即时钟周期是20ns,cnt是每个时钟加1,则当cnt==99时,就说明数了100个时钟周期,也就是时间是100*20=2000ns了。
QQ图片20170215151757.png

同样的道理,1秒钟时间,我们就是数1s/20ns= 50_000_000个时钟周期。我们也认识到这个cnt也是计数器,其加1条件是“1”,要数50_000_000个数。我们套用明德扬计数器模块,即有下面代码。
  1. always @(posedge clk or negedge rst_n)begin
  2.         if(!rst_n)begin
  3.             cnt <= 0;
  4.         end
  5.         else if(add_cnt)begin
  6.             if(end_cnt)
  7.                 cnt <= 0;
  8.             else
  9.                 cnt <= cnt + 1;
  10.         end
  11.     end

  12.     assign add_cnt = 1 ;      
  13.     assign end_cnt = add_cnt && cnt== 50_000_000-1;   
复制代码
代码中,always语句除了名字后,完全套用模板,不用更改。加1条件体现在第13行,要数多少个体现在第14行。
确定了cnt后,那么秒个位的加1条件就非常明确了,就是cnt数到50_000_000个,也就是end_cnt有效的时候。所以秒个位的加1条件是end_cnt。
秒个位要数多少个数字呢?由0到9,因此有10个。

综上所述,我们得到秒个位的代码如下表。
  1. always@(posedge clk or negedge rst_n)begin
  2.         if(rst_n==1'b0)begin
  3.             miao_g <= 0;
  4.         end
  5.         else if(add_miao_g)begin
  6.             if(end_miao_g)
  7.                 miao_g <= 0;
  8.             else
  9.                 miao_g <= miao_g + 1;
  10.         end
  11.     end

  12.     assign add_miao_g = end_cnt;
  13.     assign end_miao_g = add_miao_g && miao_g == 10-1;
复制代码
用类似于秒个位的思考方法,我们可以得到秒十位、分个位、分十位、时个位和时十位的代码,完整的代码如下表。
  1. always @(posedge clk or negedge rst_n)begin
  2.         if(!rst_n)begin
  3.             cnt <= 0;
  4.         end
  5.         else if(add_cnt)begin
  6.             if(end_cnt)
  7.                 cnt <= 0;
  8.             else
  9.                 cnt <= cnt + 1;
  10.         end
  11.     end

  12.     assign add_cnt = 1 ;      
  13.     assign end_cnt = add_cnt && cnt== 50_000_000-1;   

  14.     always@(posedge clk or negedge rst_n)begin
  15.         if(rst_n==1'b0)begin
  16.             miao_g <= 0;
  17.         end
  18.         else if(add_miao_g)begin
  19.             if(end_miao_g)begin
  20.                 miao_g <= 0;
  21.             end
  22.             else begin
  23.                 miao_g <= miao_g + 1;
  24.             end
  25.         end
  26.     end

  27.     assign add_miao_g = end_cnt;
  28.     assign end_miao_g = add_miao_g && miao_g == 10-1;

  29.     always  @(posedge clk or negedge rst_n)begin
  30.         if(rst_n==1'b0)begin
  31.             miao_s <= 0;
  32.         end
  33.         else if(add_miao_s)begin
  34.             if(end_miao_s)begin
  35.                 miao_s <= 0;
  36.             end
  37.             else begin
  38.                 miao_s <= miao_s + 1;
  39.             end
  40.         end
  41.     end

  42.     assign add_miao_s = end_miao_g;
  43.     assign end_miao_s = add_miao_s && miao_s == 6-1;

  44.     always  @(posedge clk or negedge rst_n)begin
  45.         if(rst_n==1'b0)begin
  46.             fen_g <= 0;
  47.         end
  48.         else if(add_fen_g)begin
  49.             if(end_fen_g)begin
  50.                 fen_g <= 0;
  51.             end
  52.             else begin
  53.                 fen_g <= fen_g + 1;
  54.             end
  55.         end
  56.     end

  57.     assign add_fen_g = end_miao_s;
  58.     assign end_fen_g = add_fen_g && fen_g == 10-1;

  59.     always  @(posedge clk or negedge rst_n)begin
  60.         if(rst_n==1'b0)begin
  61.             fen_s <= 0;
  62.         end
  63.         else if(add_fen_s)begin
  64.             if(end_fen_s)begin
  65.                 fen_s <= 0;
  66.             end
  67.             else begin
  68.                 fen_s <= fen_s + 1;
  69.             end
  70.         end
  71.     end

  72.     assign add_fen_s = end_fen_g;
  73.     assign end_fen_s = add_fen_s && fen_s == 6-1;

  74.     always  @(posedge clk or negedge rst_n)begin
  75.         if(rst_n==1'b0)begin
  76.             shi_g <= 0;
  77.         end
  78.         else if(add_shi_g)begin
  79.             if(end_shi_g)begin
  80.                 shi_g <= 0;
  81.             end
  82.             else begin
  83.                 shi_g <= shi_g + 1;
  84.             end
  85.         end
  86.     end

  87.     assign add_shi_g = end_fen_s;
  88.     assign end_shi_g = add_shi_g &&  shi_g ==x-1;

  89.     always  @(posedge clk or negedge rst_n)begin
  90.         if(rst_n==1'b0)begin
  91.             shi_s <= 0;
  92.         end
  93.         else if(add_shi_s)begin
  94.             if(end_shi_s)begin
  95.                 shi_s <= 0;
  96.             end
  97.             else begin
  98.                 shi_s <= shi_s + 1;
  99.             end
  100.         end
  101.     end

  102.     assign add_shi_s = end_shi_g;
  103. assign end_shi_s = add_shi_s && shi_s == 3-1;

  104. always@(*)begin
  105.         if(shi_s==2)
  106.             x =4;
  107.         else
  108.             x =10;
  109. end
复制代码
细心的读者可以发现,上面每段计数器格式都非常相似。没错,这就是明德扬设计的技巧。我们设计的这套模板,基本上可以应用于任何场合,任何时候读者只考虑两个因素就够了,不会出现丢三落四的情况,而且每次只需要考虑一个因素,保证能做出最优的设计。
如果你还未发现这代码优秀的地方,建议你百度下数字时钟的代码,好好比一比,特别是好好想想我们的设计思路,明德扬是有方法有步骤、可以做到一次性设计对,而他们的则是想到哪写到哪,每次设计都不同的想法。每次设计都是不同的思想,水平怎么能提高!
明德扬整个培训周期,都是训练类似于这种固定、专业的思维方法,无论你遇到多复杂多前卫的项目,都能用这种思维方式来设计。

对了,上面代码中,我们没有补充信号定义这些。其实我们认为这些信号定义纯属体力劳动,是根本就不需要学习的,所以我们就没列出来。读者有兴趣可必补充。另外加上数码管译码电路,那么一个完整的数字时钟代码就出来了。



标签:fpga 数字时钟

总工程师

发表于 2017-2-15 21:41:32  

PCB在线计价下单

板子大小:

cm
X
cm

层数:

2

板子数量:

10

厚度:

1.6
如果在每条程序后面加上注释会更好
回复

点赞

高级模式
您需要登录后才可以回帖 登录 | 注册

专家问答 查看更多>>
关闭

站长推荐 上一条 /7 下一条

小黑屋|手机版|Archiver| 电子发烧友 ( 粤ICP备14022951号-2 )     

GMT+8, 2017-6-25 06:22 , Processed in 0.102276 second(s), 16 queries , Memcache On.

微信扫描
快速回复 返回顶部 返回列表
-

推荐专区

技术干货集中营

专家问答

用户帮助┃咨询与建议┃版主议事

我的提问

工程师杂谈

工程师创意

工程师职场

论坛电子赛事

社区活动专版

发烧友活动

-

嵌入式论坛

单片机/MCU论坛

FPGA|CPLD|ASIC论坛

DSP论坛

嵌入式系统论坛

-

电源技术论坛

电源技术论坛

-

硬件设计论坛

电路设计论坛

电子元器件论坛

控制|传感

总线技术|接口技术

-

测试测量论坛

LabVIEW论坛

Matlab论坛

测试测量技术专区

仪器仪表技术专区

-

EDA设计论坛

multisim论坛

PCB设计论坛

proteus论坛|仿真论坛

EasyEDA-中国人自已的EDA工具

-

综合技术与应用

电机控制

智能电网

光电及显示

参考设计中心

汽车电子技术论坛

医疗电子论坛

-

开源硬件

DFRobot专区

树莓派论坛

智能硬件论坛

开发快智能硬件开发平台

Intel物联网开发者专区

Waveshare

乐美客SBC专区

Arduino论坛

BeagleBone论坛

机器人论坛

创客神器NanoPi

小钢炮CANNON

比派科技banana pi专区

-

无线通信论坛

无线通信技术专区

天线|RF射频|微波|雷达技术

-

IC设计论坛

芯片测试与失效分析

Mixed Signal/SOC[数模混合芯片设计]

Analog/RF IC设计

设计与制造封装测试

-

个人版区

阿东Verilog技术专版

直流马达驱动电路设计

LabVIEW英雄联盟

特权同学FPGA专区

-

厂商专区

灵动微电子 MM32

盈鹏飞嵌入式

TI论坛

TI Deyisupport社区

芯灵思嵌入式论坛

Tisan

米尔科技

庆科社区

WIZnet技术专区

Cypress技术论坛

飞凌嵌入式

Qualcomm技术论坛

英创嵌入式

机智云GoKit论坛

-

检测技术与质量

电磁兼容(EMC)设计与整改

安规知识论坛

检测与认证

-

消费电子论坛

手机技术论坛

平板电脑/mid论坛

音视/视频/机顶盒论坛

-

电子论坛综合区

聚丰众筹官方社区

新人报道区

聚丰供应链

-

论坛服务区

-

供求信息发布

供需广告

招聘┃求职发布区

电子展览展会专区