Verilog 学习笔记(1)12小时计时器

这篇具有很好参考价值的文章主要介绍了Verilog 学习笔记(1)12小时计时器。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

今天在刷HDLBits的时候遇到了这个比较难的关于12小时时钟设计的问题,故开个笔记记录一下自己的思路。

Verilog 学习笔记(1)12小时计时器

 

首先看下这个题目,要求我们设置一个计时12小时并可以表征上半天、下半天的时钟。这种计时问题在前面也遇到过,本质是一个分频器的问题,或者说,是一个改装计数器的问题。 也就是说将自定义不同进制的计数器,并将其串联,根据上下进位的原则来赋予各个计数器不同的权重。而就这道题而言,因为小时的范围是1到12,分钟和秒的范围是0到59,那么问题就转化成了把题目所给的两位BCD(hh, ss, mm)改装成12进制和59进制的计数器的问题。

Verilog 学习笔记(1)12小时计时器

 

当然,让我们先回到问题本身。从顶层模块看,一共有三个输入,四个输出;其中 clk为时钟,而 reset和ena都是受时钟控制的同步信号。
Verilog 学习笔记(1)12小时计时器

 

对于这两个信号而言,从题目给的波形图示例可以看出,reset是高电平有效的置零信号,且具有最高优先级;一旦reset=1,hh会被置为12,mm与ss都会被置为0。而ena是高电平有效的使能信号,当reset不为1的时候,ena控制ss能否递增;如果ena变为0,则ss保持现有值不变。

然后我们再来关注下各个输出量之间的关系。根据题目信息,不会出现hh=0的情况,也就是说,这个计时器表示的时间范围是从12:00:00到1:00:00在递增到11:59:59,下一刻回到12:00:00并且pm翻转。而另外几个量跟前面的一千赫兹分频器原理类似,当ss到达59时下一ss归0且mm进1,ss和mm均达59时下一刻二者归零且hh进1。也就是说,我们可以用两个容量为60的计数器来分别表示输出mm和ss,再用一个容量为12的计数器来表示hh。三个计数器成串联关系,从低到高依次进位,体现为某个计数器的使能信号来源于上一个计数器输出为计满值的情况,而对于最底层的ss而言,它的使能信号就是ena。

按照层次化的设计方法,在顶层模块中我们只需要对pm的情况做阐释,即每当reset信号生效时,pm为0;当reset=0时,pm在每次时间达到11:59:59时翻转;这个用一个比较简单的if-else语句就可以写出来;同时我们在顶层模块中需要实例化三个计数器。

module top_module(
    input clk,
    input reset,
    input ena,
    output pm,
    output [7:0] hh,
    output [7:0] mm,
    output [7:0] ss); 
    count60 u1 (.clk(clk), .reset(reset), .en(ena), .cnt_out(ss));
    count60 u2 (.clk(clk), .reset(reset), .en(ena&&ss==8'h59), .cnt_out(mm));
    count12 u3 (.clk(clk), .reset(reset), .en(ena&&(ss==8'h59)&&(mm==8'h59)), .cnt_out(hh));
    always @(posedge clk)
        begin
            if (reset)
                pm <= 0;
            else if (ss==8'h59&&mm==8'h59&&hh==8'h11)
                pm <= ~pm;
            else;
        end            
endmodule

这个地方需要注意的是每个计数器的使能信号;是ena和下层模块进位的相与;假设在下层模块将要进位时,时钟上升沿传入信号,但是ena恰为0,这时候如果不把ena考虑进上层模块的使能信号中的话,会造成仅有ss受ena控制不递增而上层模块递增的错误情况。

然后就是底层模块部分,先写mm和ss的60进制计数器。首先考虑的仍然是reset,而后是en,需要考虑进位关系。这里比较关键的是,进位关系实际上要考虑两点;首先当然是作为计数器计满置0的情况,另外一个是因为hh和mm都是两位BCD码,也即一共8位二进制码,每四位表示一个十进制数;所以这个时候需要从十进制的角度来考虑进位;对于hh和mm,需考虑当低四位表示的数字等于9时就存在低四位的置零和高四位进1;而当低四位表示的数字小于9时,高四位不变而低四位进1,这个用if-else语句也可实现。

module count60 (input clk, input reset, input en, output reg [7:0]cnt_out);
    always @(posedge clk)
        begin
            if (reset)
                cnt_out <= 0;
            else if (en)
                if (cnt_out == 8'h59)
                    cnt_out <= 0;
            	else if (cnt_out[3:0]==9)
                	begin
                        cnt_out[3:0] <= 0;
                        cnt_out[7:4] <= cnt_out[7:4]+1;
                    end
            else cnt_out[3:0] <= cnt_out[3:0]+1;
        end
endmodule

当然,这个地方不要忘了在if-else语句中若有多个变量的赋值需要加上begin和end。

然后进行12进制计数器的编写,跟上面的60进制基本相同,不同的一方面是当reset产生时回到12,还有当计数达到12时下一次置1。也就是说计满回归的值和置零信号产生后回归的值不同。同时也需要注意BCD码的进位情况。

module count12 (input clk, input reset, input en, output reg [7:0]cnt_out);
        always @(posedge clk)
            begin
                if (reset)
                    cnt_out <= 8'h12;
                else if (en)
                    if (cnt_out == 8'h12)
                        cnt_out <= 1;
                else if (cnt_out[3:0]==9)
                    begin
                        cnt_out[3:0] <= 0;
                        cnt_out[7:4] <= cnt_out[7:4] +1;
                    end
                else
                    cnt_out[3:0] <= cnt_out[3:0]+1;
            end
endmodule

以上就是12小时计数器的题目分析,这个题综合性比较强,算是HDLBits里面比较难的题,融合了层次化的设计方法、串联进位计数器的设计、BCD计数的设置,值得反复学习。文章来源地址https://www.toymoban.com/news/detail-445868.html

到了这里,关于Verilog 学习笔记(1)12小时计时器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Vivado设计秒表计时器实现00分00.00秒到59分59.99秒的计时(verilog语言)

    目录 0.写在最前 一、课程设计要求: 三、名词说明解释 四、Vivado代码实现部分 五、仿真测试程序 六、约束文件 七、开发板结果展示 八、关于改进/扩展 ① 增加秒与 0.1s 之间的分隔符“.”号的点亮: ② 取消 0.1s,0.01s 显示,增加小时形成“时分.秒”的显示方式 ③ 其它改

    2024年02月06日
    浏览(56)
  • qt学习:QTimer定时器+重复计时+单次计时

    在指定的间隔时间会发送出一个timeout信号,关联对应的槽函数 #includeQTimer

    2024年01月19日
    浏览(62)
  • javaScript:快乐学习计时器

    目录 一.前言 二.计时器 1.计时器的分类 2. 创建计时器的方式 创建间隔计时器 创建方式三种 1.匿名函数 2.使用函数直接作为计时器的执行函数  2.使用函数直接作为计时器的执行函数,用字符串的形式写入  3.计时器的返回值 4.清除计时器  5.延迟计时器  相关代码        

    2024年02月12日
    浏览(41)
  • 14、计时器、定时器设计与应用

    掌握同步四位二进制计数器 74LS161 的工作原理和设计方法 掌握时钟/定时器的工作原理与设计方法 任务 1:采用行为描述设计同步四位二进制计数器 74LS161 任务 2:基于 74LS161 设计时钟应用 1.创建工程并创建 Verilog 文件 建立 HDL 类型的工程 My74LS161,创建 Verilog 文件 My74LS161,

    2024年02月03日
    浏览(51)
  • 51单片机通过计时器实现倒计时

    软件 : Keil5+Proteus7 元件 : AT89C51 * 1,7SEG-MPX2-CA * 1

    2024年02月16日
    浏览(68)
  • java计时器

      在 Java中,我们有一个重要的概念:同步和异步。同步就是 Java中的线程安全,异步就是 Java中的线程非安全。 在使用 JVM时,我们一般都是用 start ()方法启动一个线程,然后设置时间,比如定时器,定时器是在某个指定的时间执行相应的任务。但是,在实际应用中,我们

    2023年04月18日
    浏览(59)
  • RIP四大计时器

    RIP 计时器(以下均以华为 ensp 中信息为参考) 希望有需要的小伙伴可以参考参考,如有误解、请指正! 一、实验原理 1. 更新计时器( Update Timer ) Update time(更新时间):指运行RIP协议的路由器向其连接口广播自己的路由信息的时间间隔(用于更新RIP路由表信息),控制

    2024年02月03日
    浏览(43)
  • WPF计时器功能

    本文实现WPF的计时器功能是通过system.timers.timer这个组件实现的。现在网上相关的资料有很多,我只是在自己的工作中刚好遇到要实现这个功能,中间也走了很多的弯路,不停的参考网上现有的资源,终于实现了基本的定时功能。希望本文可以帮助到您,让您花更少的时间来完

    2024年02月05日
    浏览(51)
  • 24秒计时器

    方案一:采用计数器(74LS192)作为核心部分。同时选择(74LS47)作为BCD码译码器来对7段数码显示管进行译码驱动,两个七段共阳数码显示管进行显示。采用计时器(NE555)制成的多谐振荡器,进行秒脉冲的输入。因为我们需要对其进行暂停、清零、报警和自动清零等控制,所

    2024年02月06日
    浏览(44)
  • Qt实现计时器

    一、样图 二、代码 mainwidow.h mainwindow.cpp main.cpp ui_mainwindow.h

    2024年02月07日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包