Verilog HDL 设计一个电子钟

基于 Verilog HDL 设计电子钟,能够进行正常计时,时间调整,时间复位的模式选择。

文章目录

  • Verilog HDL 设计一个电子钟
  • 设计思路
    • 复位设计
    • 计时设计
    • 调整设计
  • 关键代码
  • 源代码
  • 设置引脚

设计思路

电子时钟分为主模块(time)和数码管模块(smg):
主模块用来控制时、分、秒的逻辑,数码管模块用来显示时间;计时实际就是进行计数,间隔为1秒;
60秒:分成个位和十位实现,个位:0-9,到9向十位进1;十位:0-6,到6向分钟进1;
60分:分成个位和十位实现,个位:0-9,到9向十位进1;十位:0-6,到6向小时进1;
24时:直接设计0-24,reg[5:0] xy(6位的二进制数),但分成个位、十位进行数码管显示,个位取小时除以10取余,十位取小时除以10取整。

复位设计

用硬件上的开关(SW1)实现时间复位,就是实现电子时钟全部清零,并且不再改变(一直为0),除非关闭时间复位。

计时设计

首先进行时间复位,再关闭时间复位,从0进行正常计时。

调整设计

只调整分钟和小时,用硬件上的开关控制(SW2,SW3),依然是1秒进行计数。
需要再引入两个变量:xn,xn1;当时间调整开关打开时,让xn或xn1进行单独计时,同时再赋值给分钟或小时会显示的变量,调分钟时调的是分的个位。

关键代码

//1S定时时钟产生
reg [31:0]  count;
reg clk_1s; //0,1 一秒钟
always @(posedge clk)  if(count==24_000_000-1)begincount <= count+1;clk_1s <= 0;endelse if(count<48_000_000-1)count <= count+1;else begincount <= 0;clk_1s <= 1;        end

源代码

主模块

//
//主模块time
//
module time(
input SW1,//控制复位
input SW2,//控制调分钟
input SW3,//控制调小时
output  [7:0] sel,
output  [7:0] seg,
input clkin//时钟
);      wire clk;
pll4 pll4_inst0(.inclk0(clkin),//12Mhz.c0(clk)//48Mhz
);//1S定时时钟产生
reg [31:0]  count;
reg clk_1s;
always @(posedge clk)  //always语句相当于一个死循环if(count==24_000_000-1)begincount <= count+1;clk_1s <= 0;endelse if(count<48_000_000-1)count <= count+1;else begincount <= 0;clk_1s <= 1;      endreg [3:0] dout1,dout2,dout3,dout4,dout5,dout6;//时、分、秒的个位和十位
reg co_1;//秒的个位向十位的进位
reg co_2;//秒的十位向分的个位的进位
reg co_3;//分的个位向十位的进位
reg co_4;//分的十位向时的进位//秒的个位实现
always@(posedge clk_1s,negedge SW1)
beginif(!SW1)     //如果SW1关闭时钟复位dout1<=0;else        //SW1打开进行计时(0-9)beginif(dout1<9)begindout1 <= dout1 +1;   //进行加1操作co_1<=0;            //此时进位数为0;endelse                        //秒的个位为9时begindout1 <= 0;       //重新赋值为0co_1<=1;        //此时进位数为1endend
end //秒的十位的实现
always @(posedge co_1,negedge SW1)
beginif(!SW1)dout2<=0;elsebeginif(dout2<5)begindout2 <= dout2 +1;   co_2<=0;endelse begindout2 <= 0;        co_2<=1;endend
end //分的个位的实现
always @(posedge co_2,negedge SW1,posedge SW2)
beginif(!SW1)dout3<=0;else        //SW1打开才执行以下代码begin if(SW2)  //SW2打开执行以下代码,即调分钟时beginif(xn<=9)  begindout3<=xn;  //这时直接赋值co_3<=0;    //进位为0endelse begindout3<=0;  //xn为10时,分的个位重新赋值为0co_3<=1;  //进位为1;endendelse   //SW2关闭执行以下代码,即不调分,正常计时beginif(dout3<9)begindout3 <= dout3 +1; co_3<=0;endelse begindout3 <= 0;        co_3<=1;endend  endend//如果要调分钟,引入变量xn(0-9)
reg [3:0] xn;
always @(posedge clk_1s,negedge SW1,negedge SW2)
beginif(!SW1)  //如果SW1关闭时钟复位xn<=0;else      //SW1打开才执行以下代码beginif(!SW2)//如果SW2关闭,即不调分钟时:xn不变xn<=xn;else    //SW2打开beginif(xn<=9) xn <= xn +1;//此时xn进行计时else xn <= 0;//xn为十时再重新赋值为0       end end
end//分的十位的实现
always @(posedge co_3,negedge SW1)
beginif(!SW1)dout4<=0;elsebeginif(dout4<5)begindout4 <= dout4 +1;   co_4<=0;endelse begindout4 <= 0;        co_4<=1;endend  end//时的实现
reg[5:0] xy;
reg x;      //是否进行调小时操作的标志
always @(posedge co_4,negedge SW1,posedge SW3)
beginif(!SW1)dout5<=0;else   //SW1打开执行以下代码beginif(SW3)  //SW3打开时执行下面代码,即要调时begindout5<=xn1%10; //将xn1除以10取余赋值给时的个位dout6<=xn1/10;//将xn1除以10取整赋值给时的十位x<=1;   //此时x为1标志进行了调时endelse //SW3关闭执行以下代码beginif(x==1) //调时后beginx<=0;  //这时将x赋值为0if(xn1<23)xy<=xn1+1;//将这时的xy赋值为调时后的xn1再加1elsexy<=0;//xn1==23时,xy赋值为0endelse //调时后x又变为0,正常计时beginif(xy<23)xy<=xy+1;elsexy<=0;enddout5<=xy%10;//将xy除以10取余赋值给时的个位dout6<=xy/10;//将xy除以10取整赋值给时的十位endend end//如果要调时,引入变量xn1(0-24)
reg [5:0] xn1;
always @(posedge clk_1s,negedge SW1,negedge SW3)
beginif(!SW1)xn1<=0;elsebeginif(!SW3)xn1<=xn1;elsebeginif(xn1<=22)xn1 <= xn1 +1;else xn1 <= 0;     end end
end//调用数码管模块
smg smg_inst
(.clk(clk) ,    // input  clkin.d1(d1) ,    // input [4:0] d1.d2(d2) ,  // input [4:0] d2.d3(d3) ,  // input [4:0] d3.d4(d4) ,  // input [4:0] d4.d5(d5) ,  // input [4:0] d5.d6(d6) ,  // input [4:0] d6.d7(d7) ,  // input [4:0] d7.d8(d8) ,  // input [4:0] d8.sel(sel) ,    // output [7:0] sel.seg(seg)    // output [7:0] seg
);reg [3:0] d1, d2, d3, d4;//定义数码管显示
reg [3:0] d5, d6, d7, d8;//定义数码管显示
always @(posedge clk)
begin//显示赋值d8 <= dout1; //秒的个位d7 <= dout2; //秒的十位 d5 <= dout3; //分的个位d4 <= dout4; //分的十位 d2 <= dout5; //时的个位d1 <= dout6; //时的十位
end                 endmodule

数码管模块

//
//8位数码管显示控制模块smg
//module smg(clk, d1, d2, d3, d4, d5, d6, d7, d8, sel, seg);
input clk;
output reg [7:0] sel;
output reg [7:0] seg;   //a~g,dp
input [3:0] d1, d2, d3, d4; //d[7]-dp, d[6:0]-ASCII
input [3:0] d5, d6, d7, d8; //d[7]-dp, d[6:0]-ASCII //扫描频率:50Hz
parameter update_interval = 48000000 / 400 - 1;
reg [4:0] dat;
reg [2:0] cursel;
integer selcnt;//扫描计数,选择位
always @(posedge clk)
beginselcnt <= selcnt + 1;if (selcnt == update_interval)beginselcnt <= 0;cursel <= cursel + 1;end
end//切换扫描位选线和数据
always @(posedge clk)
begincase (cursel)3'b000: begin dat = d1; sel = ~8'b00000001; end3'b001: begin dat = d2; sel = ~8'b00000010;end3'b010: begin dat = d3; sel = ~8'b00000100; end3'b011: begin dat = d4; sel = ~8'b00001000; end3'b100: begin dat = d5; sel = ~8'b00010000; end3'b101: begin dat = d6; sel = ~8'b00100000;end3'b110: begin dat = d7; sel = ~8'b01000000; end3'b111: begin dat = d8; sel = ~8'b10000000; endendcase
end//更新段码
always @(posedge clk)
beginseg[0] <= dat[4]; //dpcase (dat[3:0])4'h00    : seg[7:1] <= ~7'b0000001; //04'h01   : seg[7:1] <= ~7'b1001111; //14'h02   : seg[7:1] <= ~7'b0010010; //24'h03   : seg[7:1] <= ~7'b0000110; //34'h04   : seg[7:1] <= ~7'b1001100; //44'h05   : seg[7:1] <= ~7'b0100100; //54'h06   : seg[7:1] <= ~7'b0100000; //64'h07   : seg[7:1] <= ~7'b0001111; //74'h08   : seg[7:1] <= ~7'b0000000; //84'h09   : seg[7:1] <= ~7'b0000100; //9 4'h0a  : seg[7:1] <= ~7'b0001000; //a 4'h0b  : seg[7:1] <= ~7'b1100000; //b 4'h0c  : seg[7:1] <= ~7'b1110010; //c 4'h0d  : seg[7:1] <= ~7'b1000010; //d 4'h0e  : seg[7:1] <= ~7'b0110000; //e 4'h0f  : seg[7:1] <= ~7'b0111000; //f default  : seg[7:1] <= ~7'b0110000;    //E-rrorendcase
endendmodule

设置引脚

源代码需要配置引脚才能运行。

verilog 设计一个电子钟相关推荐

  1. verilog设计一个分,秒定时器电路:输入时钟1KHZ进行分秒计数

    verilog设计一个分,秒定时器电路:输入时钟1KHZ进行分秒计数 目标 实现分秒计数 问题分析 首先要求1KHZ的时钟,周期为1*10e-3s,达成1秒需要1000个周期,因为没有提到占空比就偷懒 ...

  2. Verilog设计一个秒脉冲发生器(FPGA)

    本文提供用Verilog设计秒脉冲发生器的代码,且在Basys2开发板上验证通过,本代码产生的脉冲周期为1s,可通过改变if语句中的m的判定值来改变脉冲周期. 代码如下: module pps_1(i ...

  3. verilog设计一个补码加减法运算器_漫画:为什么计算机用补码存储数据?

    作者 | 漫话编程来源 | 漫话编程(ID:mhcoding)我们知道,计算机只认识0和1,现实世界中的内容,无论是文字.音频.视频等等想要通过计算机存储.计算或者展示,都需要转换二进制.就像你刚刚唱 ...

  4. 用Verilog写一个74LS160

    5-10 用Verilog设计一个功能类似74ls160的计数器. (1)解题思路 设计一个74ls160,需要知道它的功能表,以及原理图 (2)核心模块代码 module fidv1 (rd,clk ...

  5. Verilog设计实例(7)基于Verilog的数字电子钟设计

    博文目录 写在前面 正文 设计要求 设计思想 设计文件 仿真文件 参考资料 交个朋友 写在前面 前段时间,有几个小伙伴向我请教数字电子钟设计的问题,这个问题我在之前的BCD计数器以及数码管显示问题中已 ...

  6. Verilog设计实例(2)一步一步实现一个多功能通用计数器

    博文目录 写在前面 正文 普通的二进制计数器 电路设计 行为仿真 普通的格雷码计数器 电路设计 行为仿真 LFSR 电路设计 行为仿真 多功能计数器 电路设计 行为仿真 生成语句实现方式 电路设计 行 ...

  7. Verilog HDL语言设计一个比较电路

    设计一个比较电路,当输入的一位8421BCD码大于4时,输出为1,否则为0,进行功能仿真,查看仿真结果,将Verilog代码和仿真波形图整理入实验报告. 代码: module yanxu12(in,o ...

  8. 【verilog】设计一个测试文件,产生一个周期为2微秒,占空比为3:1的时钟信号

    〇.前情提要 帮可爱的涛涛看题,顺便复习一下verilog. 参考: Verilog测试:TestBench结构 https://blog.csdn.net/qq_26652069/article/d ...

  9. (135)Verilog HDL:设计一个加法器之Adder100i

    (135)Verilog HDL:设计一个加法器之Adder100i 1.1 目录 1)目录 2)FPGA简介 3)Verilog HDL简介 4)VVerilog HDL:设计一个加法器之Adder ...

最新文章

  1. 数据结构利器之私房STL(上)
  2. SpringCloud教程- 服务链路追踪(Spring Cloud Sleuth)(SpringCloud版本Greenwich.SR4)
  3. php oauth 扩展,PHP 安装 Oauth 扩展
  4. asp.net core中负载均衡场景下http重定向https的问题
  5. 草稿 图片盒子定时器模式窗口
  6. python进程池_python进程池剖析(一)
  7. 年总结(八):关于思考的重新认识
  8. 946. Validate Stack Sequences验证栈序列
  9. Facebook推出高速光网络技术将共享
  10. 基于mysql的报表工具有哪些?值得推荐的mysql报表工具
  11. mysql 锁机制与原理详解
  12. CentOS支持NTFS格式
  13. python调用pyd_Python import / pyd / dll
  14. 屏幕正中间浮窗html,HTML 纯css浮窗居中和打开or关闭
  15. 【pytest】三、pytest用例管理框架的前后置(固件、夹具)setup和teardown,及封装
  16. 最后的舞,请与我一起跳
  17. 当Androidstudio添加权限后仍然报错java.lang.SecurityException: Permission Denial
  18. 假设有一段英文,其中有单词中间的字母i误写为I,请编写程序进行矫正。
  19. Cortex M3 数据观察点与跟踪(DWT)
  20. PyQt5 作图之 pyqtgraph PlotWidget 代码结构拆解

热门文章

  1. 7种方式实现斐波那契数列
  2. 腾讯云服务器免费证书验证,免费申请腾讯云https证书方法
  3. mysql在windows上的安装文件_MySQL安装详细图解,在Window上的详细安装步骤图解
  4. Linux网络编程学习笔记
  5. 开发过程中经常犯的低级错误
  6. android line分享代码,Android 分享到Line的两种方式
  7. 更改oracle 表空间大小,更改oracle数据库表空间大小
  8. mp3 在线编辑, 音效下载
  9. EV-HC32F460开发资料准备
  10. 记录SQL查询汉字、字母、数字