名称:基于FPGA的简易计时闹钟设计Verilog代码VIVADO仿真(文末获取)
软件:VIVADO
语言:Verilog
代码功能:
简易计时闹钟:有四位数码管,前两位计分钟,表示00~99分钟,后面两位记秒,值为00~59秒。有三个按键,第一个是分键,第二个是秒键,第三个是启动/暂停键。功能:分秒两键同时按下清零且停止计时,外于设置态,按一次分键分钟加1, 99增1变为0;按一次秒键秒增1,59增1变为0。此状态下按启动/暂停键开始计时,设置值为0000则为正计时,设置值为非零值则为倒计时。正计时时,按启动/暂停键会暂停计时,再按启动/暂停键则会继续计时。倒计时时,减到零时停止减数且发出警示蜂鸣声,直到启动/暂停键被按下时进入设置态且同时显示前设置值和停止发出蜂鸣声。
1. 工程文件
2. 程序文件
3. 程序编译
4. Testbench
5. 仿真图
整体仿真图
同时按下分秒按键,进入设置态,设置00:00,进入正计时
暂停
继续正计时
同时按下分秒按键,进入设置态,设置02:02,进入倒计时
倒计时
倒计时结束,蜂鸣器信号拉高
再按下启动/暂停键停止蜂鸣器发声
部分代码展示:
`timescale 1ns / 1ps // // Company: // Engineer: // // Create Date: 2019/12/12 21:43:12 // Design Name: // Module Name: timer // Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // //简易计时闹钟:有四位数码管,前两位计分钟,表示00~99分钟,后面两位记秒,值为00~59秒。 //有三个按键,第一个是分键,第二个是秒键,第三个是启动/暂停键。 //功能:分秒两键同时按下清零且停止计时,外于设置态,按一次分键分钟加1, 99增1变为0;按一次秒键秒增1,59增1变为0。 //此状态下按启动/暂停键开始计时,设置值为0000则为正计时,设置值为非零值则为倒计时。 //正计时时,按启动/暂停键会暂停计时,再按启动/暂停键则会继续计时。 //倒计时时,减到零时停止减数且发出警示蜂鸣声,直到启动/暂停键被按下时进入设置态且同时显示前设置值和停止发出蜂鸣声。 // module timer(clk,KEY_1,KEY_2,KEY_3,hummer,min_ten_display,min_one_display,sec_ten_display,sec_one_display); input clk;//时钟1Hz input KEY_1;//分键,为1表示按下 input KEY_2;//秒键,为1表示按下 input KEY_3;//启动/暂停键,为1表示按下 output hummer;//蜂鸣器,为1表示响 //数码管 output [7:0] min_ten_display;//分钟十位 output [7:0] min_one_display;//分钟个位 output [7:0] sec_ten_display;//秒钟十位 output [7:0] sec_one_display;//秒钟个位 reg [7:0] min_ten_display;//分钟十位 reg [7:0] min_one_display;//分钟个位 reg [7:0] sec_ten_display;//秒钟十位 reg [7:0] sec_one_display;//秒钟个位 //定义状态 reg [2:0] current_state=3'd0; reg [2:0] next_state=3'd0; parameter S_Begin=3'd0; parameter S_CLR=3'd1;//清零 parameter S_Setting=3'd2;//设置态 parameter S_Start=3'd3;//启动 parameter S_Positive=3'd4;//正计时 parameter S_Negedge=3'd5;//倒计时 parameter S_Pause=3'd6;//暂停 parameter S_Quit=3'd7;//停止 reg [3:0] minute_tens=4'd0;//分钟十位 reg [3:0] minute_ones=4'd0;//分钟个位 reg [3:0] second_tens=4'd0;//秒钟十位 reg [3:0] second_ones=4'd0;//秒钟个位 reg [3:0] minute_tens_buf=4'd0;//分钟十位 reg [3:0] minute_ones_buf=4'd0;//分钟个位 reg [3:0] second_tens_buf=4'd0;//秒钟十位 reg [3:0] second_ones_buf=4'd0;//秒钟个位 //三段式状态机设计 //第一段 always@(posedge clk) current_state<=next_state; //第二段 always@(*) case(current_state) S_Begin: if(KEY_1==1 && KEY_2==1)//2键同时按下 next_state=S_CLR;//清零 else next_state=S_Begin; S_CLR: next_state=S_Setting;//设置态 S_Setting: if(KEY_3==1)//启动暂停键 if(minute_tens==4'd0 && minute_ones==4'd0 && second_tens==4'd0 && second_ones==4'd0)//设置值为0000则为正计时 next_state=S_Positive;//设置值为0000则为正计时 else next_state=S_Negedge;//设置值为非零值则为倒计时 else next_state=S_Setting;//设置态 S_Positive: if(KEY_3==1)//启动暂停键 next_state=S_Pause;//暂停计时 else if(KEY_1==1 && KEY_2==1)//2键同时按下 next_state=S_CLR;//清零 else next_state=S_Positive;//正计时 S_Negedge: if(minute_tens==4'd0 && minute_ones==4'd0 && second_tens==4'd0 && second_ones==4'd0)//减到0时 next_state=S_Quit;//停止计时 else next_state=S_Negedge; S_Pause: if(KEY_3==1)//启动暂停键 next_state=S_Positive;//正计时 else next_state=S_Pause;//暂停计时 S_Quit: if(KEY_3==1)//启动暂停键 next_state=S_Setting;//设置态 else next_state=S_Quit;//停止 default:; endcase //第三段 always@(posedge clk) case(current_state) S_CLR:begin//清零 minute_tens<=4'd0; minute_ones<=4'd0; second_tens<=4'd0; second_ones<=4'd0; end S_Setting:begin//设置时间 minute_tens_buf<=minute_tens;//分钟十位 minute_ones_buf<=minute_ones;//分钟个位 second_tens_buf<=second_tens;//秒钟十位 second_ones_buf<=second_ones;//秒钟个位 if(KEY_1==1)//分 begin if(minute_tens==4'd9 && minute_ones==4'd9)//到99清零 begin minute_tens<=4'd0; minute_ones<=4'd0; end else if(minute_ones==4'd9)//个位到9,十位加1 begin minute_tens<=minute_tens+4'd1; minute_ones<=4'd0; end else begin minute_tens<=minute_tens; minute_ones<=minute_ones+4'd1;//个位加1 end end if(KEY_2==1)//秒 begin if(second_tens==4'd5 && second_ones==4'd9)//到59清零 begin second_tens<=4'd0; second_ones<=4'd0; end else if(second_ones==4'd9)//个位到9,十位加1 begin second_tens<=second_tens+4'd1; second_ones<=4'd0; end else begin second_tens<=second_tens; second_ones<=second_ones+4'd1;//个位加1 end end end S_Positive://正计时 if(minute_tens==4'd9 && minute_ones==4'd9 && second_tens==4'd5 && second_ones==4'd9)begin//99分59秒时清零 minute_tens<=4'd0; minute_ones<=4'd0; second_tens<=4'd0; second_ones<=4'd0; end else if(minute_ones==4'd9 && second_tens==4'd5 && second_ones==4'd9) begin//x9:59时分钟十位加1,其他清零 minute_tens<=minute_tens+4'd1; minute_ones<=4'd0; second_tens<=4'd0; second_ones<=4'd0; end else if(second_tens==4'd5 && second_ones==4'd9) begin//59秒时分钟个位加1,秒清零 minute_tens<=minute_tens; minute_ones<=minute_ones+4'd1;
源代码
扫描文章末尾的公众号二维码