赞
踩
目录
功能:1.时钟 2.秒表 3.闹钟 4.调时 5.音乐系统
输入:1.50MHZ时钟信号 2.按键
输出:1.数码管位选 2.数码管段选 3.扬声器 4.模式灯
按键包括:1.初始化 2.模式选择 3.调时位选 4.时间加 5.时间减
6.调时确认 7.秒表开始/暂停 8.秒表清零 9.闹钟开关
把电路分成以下几个模块设计:
1.顶层模块 2.按键消抖模块 3.模式选择模块 4.消抖例化输出模块
5.分频器模块 6.计数器模块(时钟) 7.调时模块 8.音乐系统模块
9.秒表模块 10.数码管显示模块
消抖模块:(输入:clk、rst_n、key_in;输出:key_state、key_flag)消抖模块未采用状态机,而是采用两个计数器1,2。计数器1在按键为高电平时计数,低电平为零。计数器2在按键为低电平时计数,高电平为零。当计数满1_000_000(20ms)时立即对key_state进行状态转换,并判断出下降沿。
模式选择模块:(输入:clk、rst_n、key_in;输出:[1:0]model(模式))实质上是一个手动计数器。00、01、10、11循环。
消抖例化输出模块:(输入:clk、rst_n、key_in;输出:adjust_shif(调时位选)、key_up(时间加)、key_down(时间减)、pause(秒表信号)、clear(秒表清零信号))运用generate对各个按键进行例化。当按键按下pause进行0、1切换。
分频器模块:(输入:clk、rst_n;输出:clk_out)实质上是一个计数器。parameter CNT_MAX = 25_000_000;定义CNT_MAX方便例化。
计数器模块(时钟):(输入:clk、rst_n、[1:0]model(模式)、key_input(调时确认) 、[23:0]adjust_time_num(时钟调时值);输出:[23:0]time_num(时钟值)、time_led(整点报时信号))例化分频器产生1s上升沿,进行计时。并且判断调时确认信号为高电平时,时钟值等于时钟调时值。当分、秒为零时产生2s整点报时高电平信号(len_flag)。
调时模块:(输入:clk、rst_n、[1:0]model(模式)、adjust_shif(调时位选)、key_up(时间加)、key_down(时间减)、[23:0]time_num(时钟值);输出:[23:0]adjust_time_num、[15:0]adjust_clock_num)调时模块包括时钟调时和闹钟调时。每次切换到调试功能显示当前时间。
音乐系统模块:(输入:clk、rst_n、[15:0] adjust_clock_num、[23:0] time_num、key_alarm、time_led;输出:beep)想要实现《小星星》歌曲的播放首先需要找到对应简谱,并根据曲调找到相应的振动频率。定义一个count_end,我们可在不同音调下对count_end赋值,以此我们利用计数器(计数上限为count_end),每当到达上限beep便翻转一次就可实现不同频率声音的输出。在电路测试过程中我们发现,声音如果连续不断且遇到两个连续的相同短音调时,会连在一起,仿佛就是一个长音调。在两个音调之间插入一个短暂的无声状态可以很好解决这个问题。整点报时就是四个短音和一个长音之间插入一个短暂的无声状态。
秒表模块:(输入:clk、rst_n、[1:0]model、pause、clear(同步清零);输出:[23:0]stop_watch_num)例化分频器产生10ms上升沿,当秒表信号pause为1时计数器计数。到达显示上限自动清零,也可手动清零。
数码管显示模块:(输入:clk、rst_n、[1:0]model、[23:0]time_num、[23:0]adjust_time_num、[15:0]adjust_clock_num、[23:0]stop_watch_num;输出:[5:0]sel、[6:0]seg)定义一个[23:0]show_num,选择赋值,最终输出show_num的值。
对时钟功能进行仿真,我们看到数码管秒的个位变化一次经历了1.00206ms(仿真时参数缩小了1/1000)并且时钟在235959之后变为000000符合要求。
切换模式功能正常
秒表模式按键功能正常
上面这张图是对秒表计时的仿真图,秒表十位变化一次经历了0.1ms,因为参数设为1/1000,实际应该经过100ms,而理论也应经过100ms.
这部分是对调试模式下加减按钮的仿真,从仿真图可以看到减计数功能正常
这一部分是对调时功能的仿真图。依图我们可以知道,在调试完成并按下调时确认键后。我们迅速调至时钟模式便可以看到时钟模式下显示的数值就是我们设置的数值,并且时钟能够正常计数。这证明调时功能正常。
A. 计时功能:包括时、分、秒的计时,对数字钟来说,可以实现 1 天以内精确至1秒的计时,将小时和分钟显示在数码管上。
B. 闹钟功能:使用按键来开启或关闭闹钟功能,可设定闹钟定时的小时和分钟值,并用 LED 灯指示是否设置了闹钟功能。在闹钟定时到的时刻,启动闹铃响,响声持续一段时间后自动停止,也可以按键关闭闹铃响声。
C. 校时功能:通过按键对小时、分钟能手动调整以校准时间。
D. 设置整点报时功能:每逢整点产生持续 1s 的“嘀嘀嘀嘀——嘟”四短一长的报时音。
扩展功能:
E.秒表功能:只对秒计时,可以随时暂停与启动,包括重置,将秒的计时显示在数码管上。
F.音乐功能:在闹钟功能部分加了音乐,闹铃响声为音乐《小星星》。
- module CourseDesign_513(
- input clk, //50MHz
- input rst_n, //初始化
- input [6:1] key_in, //按键输入
- input key_input, //设置时间的确认按键
- input key_alarm, //闹钟开关
- output [5:0] sel, //数码管位选
- output [7:6] sel_0, //数码管不显示
- output [6:0] seg, //数码管段选
- output beep, //闹钟音乐
- output reg [3:0] model_led //模式led
- );
- /*=============================定义变量==================================*/
- wire [1:0] model; //模式
- wire time_led; //整点报时(闪烁)
- wire [1:0] adjust_shif; //换位设置
- wire key_up; //加
- wire key_down; //减
- wire pause; //秒表暂停
- wire clear; //秒表清空
- wire [23:0] adjust_time_num; //时钟校准数值
- wire [23:0] time_num; //时钟数值
- wire [15:0] adjust_clock_num; //闹钟数值
- wire[23:0] stop_watch_num; //秒表数值
- assign sel_0=2'b00;
- /*=============================功能模块==================================*/
- key_module h1(
- clk,
- rst_n, //初始化
- key_in, //按键输入
- model, //模式
- adjust_shif, //调整时间
- key_up, //调整时间+
- key_down, //调整时间-
- pause, //秒表暂停/开始
- clear //秒表清除
- );
- /*=============================时钟==================================*/
- time_counter h2(
- clk, //分频clk_1s,
- rst_n, //初始化
- model, //模式
- adjust_time_num, //时间调整倠
- key_input, //设置时间的确认按键
- time_num, //时钟数值
- time_led //整点报时
- );
- /*==============================声音模块=================================*/
- alarm_music h3(
- clk,
- rst_n, //初始化
- adjust_clock_num, //闹钟调整值,只有小时和分钟
- time_num, //时钟数值
- key_alarm, //闹钟开关
- time_led, //整点报时
- beep
- );
- /*=============================秒表==================================*/
- stop_watch h4(
- clk,
- rst_n, //初始化
- model, //模式
- pause, //秒表暂停/开始
- clear, //秒表清除
- stop_watch_num //秒表数值
- );
- /*=============================调时==================================*/
- adjust_module h5(
- clk,
- rst_n, //初始化
- model, //模式
- adjust_shif, //调整时间时
- key_up, //调整时间+
- key_down, //调整时间-
- time_num, //时钟数值
- adjust_time_num, //时钟校准数值
- adjust_clock_num //闹钟数值
- );
- /*=============================数码管显示==================================*/
- led_seg7_display h6(
- clk,
- rst_n, //初始化
- model, //模式
- time_num, // 时钟数据
- adjust_time_num, // 调整时钟数据
- adjust_clock_num, // 调整闹钟数据
- stop_watch_num, // 秒表
- sel, // 数码管位选
- seg // 数码管段选
- );
- //================================模式显示LED===============================
- always@(model)
- case (model)
- 2'b00:model_led=4'b0001;
- 2'b01:model_led=4'b0010;
- 2'b10:model_led=4'b0100;
- 2'b11:model_led=4'b1000;
- endcase
- endmodule
- module key_filter( //消抖模块
- input clk,
- input rst_n,
- input key_in,
- output reg key_state, //状态说明
- output key_flag //下降沿
- );
- parameter CNT_MAX = 1_000_000; //20ms计数值 1_000_000
- //为方便仿真1_000
- reg [19:0] key_H, key_L; //计数变量
- //------------------按键为低 计数--------------------------
- always@(posedge clk, negedge rst_n) begin
- if(!rst_n)
- key_H <= 20'd0;
- else begin
- if(key_in)
- key_H <= key_H + 1;
- else
- key_H <= 20'd0;
- end
- end
- //-------------------按键为高 计数-------------------------
- always@(posedge clk, negedge rst_n) begin
- if(!rst_n)
- key_L <= 20'd0;
- else begin
- if(!key_in)
- key_L <= key_L + 1;
- else
- key_L <= 20'd0;
- end
- end
- //-------------------key_state输出判断--------------------
- always@(posedge clk, negedge rst_n) begin
- if(!rst_n)
- key_state <= 1'b0;
- else begin
- if(key_H > CNT_MAX)
- key_state <= 1'b1;
- else if(key_L > CNT_MAX)
- key_state <= 1'b0;
- end
- end
- //---------------------按键按下 下降沿判断----------------
- reg state1, state2;
- always@(posedge clk, negedge rst_n) begin
- if(!rst_n) begin
- state1 <= 1'b0;
- state2 <= 1'b0;
- end
- else begin
- state1 <= key_state;
- state2 <= state1;
- end
- end
- assign key_flag = (!state1) & state2; //按键按下,flag为高
- endmodule
- module model_change( //改变功能模块
- input clk,
- input rst_n,
- input key_in,
- output [1:0] model
- );
- //----------------- 模式:00:时钟,01:闹钟,10:秒表,11:调时 ------------
- reg [1:0] cnt;
- always@(posedge clk, negedge rst_n) begin
- if(!rst_n) begin
- cnt <= 2'd0;
- end
- else if(key_in) //按键按下
- cnt <= cnt + 1'b1; // 00 01 10 11循环
- else
- cnt <= cnt;
- end
- assign model = cnt;
- endmodule
- module key_module(
- input clk,
- input rst_n,
- input [6:1] key_in,
- output [1:0] model, //模式
- output reg [1:0] adjust_shif, //调整时间
- output key_up, //调整时间+
- output key_down, //调整时间-
- output reg pause, //秒表暂停/开始
- output clear //秒表清除
- );
- //-------- 例化key_filter,产生按键对应的高电平脉冲 -----------
- wire [6:1] key_out;
- genvar i;
- generate
- for(i = 1; i < 7; i = i + 1) begin: specify7_key_filter //块名
- key_filter fliter1(
- .clk (clk),
- .rst_n (rst_n),
- .key_in (key_in[i]),
- .key_state (),
- .key_flag (key_out[i])
- );
- end
- endgenerate
- assign key_up = key_out[3];
- assign key_down = key_out[4];
- assign clear = key_out[6];
- //----------- 例化 model_change ----------------
- model_change model1(
- .clk (clk),
- .rst_n (rst_n),
- .key_in (key_out[1]),
- .model (model)
- );
- //------------------- adjust_shif 调整时间位置 ---------------
- always@(posedge clk, negedge rst_n) begin
- if(!rst_n) begin
- adjust_shif <= 2'b00;
- end
- else begin
- if(key_out[2]) begin
- adjust_shif <= adjust_shif + 1'b1;
- if(adjust_shif == 2'b10)
- adjust_shif <= 2'b00;
- end
- if(key_out[1]) // model模式改变时,回到初始位
- adjust_shif <= 2'b00;
- end
- end
- //---------------- pause 秒表暂停/开始 --------------------
- always@(posedge clk, negedge rst_n) begin
- if(!rst_n)
- pause <= 1'b0;
- else if(key_out[5])
- pause <= ~pause;
- else if(model != 2'b10) //退出秒表模式暂停
- pause <= 1'b0;
- else
- pause <= pause;
- end
- endmodule
- module clk_div(
- input clk_in,
- input rst_n,
- output clk_out
- );
- //------------------------------------------------
- parameter CNT_MAX = 25_000_000; //任意值
- reg clk_reg;
- reg [24:0] cnt;
- //-------------------------------------------------
- assign clk_out = clk_reg;
- always@(posedge clk_in, negedge rst_n) begin
- if(!rst_n) begin
- clk_reg <= 1'b0;
- cnt <= 28'd0;
- end
- else begin
- if(cnt == CNT_MAX - 1) begin
- cnt <= 28'd0;
- clk_reg <= ~clk_reg;
- end
- else begin
- cnt <= cnt + 1'b1;
- clk_reg <= clk_reg;
- end
- end
- end
- endmodule
- module time_counter(
- input clk, //clk_1s,
- input rst_n,
- input [1:0] model,
- input [23:0] adjust_time_num,
- input key_input,
- output [23:0] time_num,
- output time_led
- );
- //------------------------- 1s时钟上升沿-----------------
- wire clk_1s;
- clk_div #(.CNT_MAX(25000000)) clk_div_1s(
- .clk_in (clk),
- .rst_n (rst_n),
- .clk_out (clk_1s)
- );//25000000 仿真改为25000
- reg clk_reg1, clk_reg2;
- wire pos_1s;
- always@(posedge clk, negedge rst_n) begin
- if(!rst_n) begin
- clk_reg1 <= 1'b0;
- clk_reg2 <= 1'b0;
- end
- else begin
- clk_reg1 <= clk_1s;
- clk_reg2 <= clk_reg1;
- end
- end
- assign pos_1s = clk_reg1 & (!clk_reg2);//上升沿
- //---------------------正常时间计数(时、分、秒)----------
- reg [3:0] sec0;
- reg [3:0] sec1;
- reg [3:0] min0;
- reg [3:0] min1;
- reg [3:0] hour0;
- reg [3:0] hour1;
- always@(posedge clk, negedge rst_n) begin
- if(!rst_n) begin
- sec0 <= 4'd5; //默认时间23:59:55
- sec1 <= 4'd5;
- min0 <= 4'd9;
- min1 <= 4'd5;
- hour0 <= 4'd3;
- hour1 <= 4'd2;
- end
- else begin
- if(pos_1s) begin
- sec0 <= sec0 + 1'b1;
- if(sec0 == 4'd9) begin
- sec0 <= 4'd0;
- sec1 <= sec1 + 1'b1;
- if(sec1 == 4'd5) begin
- sec1 <= 4'd0;
- min0 <= min0 + 1'b1;
- if(min0 == 4'd9) begin
- min0 <= 4'd0;
- min1 <= min1 + 1'b1;
- if(min1 == 4'd5) begin
- min1 <= 4'd0;
- hour0 <= hour0 + 1'b1;
- if(hour0 == 4'd9) begin
- hour0 <= 4'd0;
- hour1 <= hour1 + 1'b1;
- end
- end
- end
- end
- end
- end
- if(hour1 ==4'd2 && hour0 == 4'd4) begin
- hour1 <= 4'd0;
- hour0 <= 4'd0;
- end
- if((model == 2'b11)&&key_input) begin //时间校准
- {hour1, hour0, min1, min0, sec1, sec0} <= adjust_time_num[23:0];
- end
- end
- end
- //---------------- 整点报时 --------------------------------------
- reg len_flag;
- always@(posedge clk, negedge rst_n) begin
- if(!rst_n)
- len_flag <= 1'b0;
- else if(time_num[15:0] == 16'b0) //分钟和秒都归零
- len_flag <= 1'b1;
- else if(sec0 == 4'd2) //2s
- len_flag <= 1'b0;
- else
- len_flag <= len_flag;
- end
- assign time_led = len_flag;
- //------------------- 输出赋值---------------------
- assign time_num = {hour1, hour0, min1, min0, sec1, sec0};
- endmodule
- module adjust_module(
- input clk,
- input rst_n,
- input [1:0] model, //模式P:时钟,01:闹钟,10:秒表,11:调无
- input [1:0] adjust_shif, //调整时间时,调整位置P:秒个位Q:分个位P:时个位
- input key_up, //调整时间+
- input key_down, //调整时间-
- input [23:0] time_num,
- output [23:0] adjust_time_num,
- output [15:0] adjust_clock_num
- );
- //---------------------------- 闹钟变量 ---------------------------
- reg [3:0] clock_min0;
- reg [3:0] clock_min1;
- reg [3:0] clock_hour0;
- reg [3:0] clock_hour1;
- //----------------------------- 闹钟设置 -------------------------
- always@(posedge clk, negedge rst_n) begin
- if(!rst_n) begin
- clock_min0 <= 4'd0;
- clock_min1 <= 4'd0;
- clock_hour0 <= 4'd0;
- clock_hour1 <= 4'd0;
- end
- else if(model == 2'b01) begin //闹钟模式,只有小时、分钟
- if(adjust_shif == 2'b00) begin //调分钟个位
- if(key_up) begin
- clock_min0 <= clock_min0 + 1'b1;
- if(clock_min0 == 4'd9)
- clock_min0 <= 4'd0;
- end
- else if(key_down) begin
- clock_min0 <= clock_min0 - 1'b1;
- if(clock_min0 == 4'd0)
- clock_min0 <= 4'd9;
- end
- end
- else if(adjust_shif == 2'b01) begin //调分钟十位
- if(key_up) begin
- clock_min1 <= clock_min1 + 1'b1;
- if(clock_min1 == 4'd5)
- clock_min1 <= 4'd0;
- end
- else if(key_down) begin
- clock_min1 <= clock_min1 - 1'b1;
- if(clock_min1 == 4'd0)
- clock_min1 <= 4'd5;
- end
- end
- else begin //小时个位
- if(key_up) begin
- clock_hour0 <= clock_hour0 + 1'b1;
- if(clock_hour0 == 4'd9) begin
- clock_hour0 <= 4'd0;
- clock_hour1 <= clock_hour1 + 1'b1;
- end
- if(clock_hour1 ==4'd2 && clock_hour0 == 4'd3) begin
- clock_hour1 <= 4'd0;
- clock_hour0 <= 4'd0;
- end
- end
- else if(key_down) begin
- clock_hour0 <= clock_hour0 - 1'b1;
- if(clock_hour0 == 4'd0) begin
- clock_hour0 <= 4'd9;
- clock_hour1 <= clock_hour1 - 1'b1;
- end
- if(clock_hour1 ==4'd0 && clock_hour0 == 4'd0) begin
- clock_hour1 <= 4'd2;
- clock_hour0 <= 4'd3;
- end
- end
- end
- end
- end
- //-------------------------- 校准时间变量 --------------
- reg [3:0] adj_sec0;
- reg [3:0] adj_sec1;
- reg [3:0] adj_min0;
- reg [3:0] adj_min1;
- reg [3:0] adj_hour0;
- reg [3:0] adj_hour1;
- //----------------------------- 校准时间-----------------
- always@(posedge clk, negedge rst_n) begin
- if(!rst_n) begin
- adj_sec0 <= 4'd5;
- adj_sec1 <= 4'd3;
- adj_min0 <= 4'd9;
- adj_min1 <= 4'd5;
- adj_hour0 <= 4'd3;
- adj_hour1 <= 4'd2;
- end
- else if(model == 2'b11)begin
- case(adjust_shif) //调时 位置
- 2'b00: begin //秒个位
- if(key_up) begin
- adj_sec0 <= adj_sec0 + 1'b1;
- if(adj_sec0 == 4'd9) begin
- adj_sec0 <= 4'd0;
- adj_sec1 <= adj_sec1 + 1'b1;
- if(adj_sec1 == 4'd5) begin
- adj_sec1 <= 4'd0;
- end
- end
- end
- else if(key_down) begin
- adj_sec0 <= adj_sec0 - 1'b1;
- if(adj_sec0 == 4'd0) begin
- adj_sec0 <= 4'd9;
- adj_sec1 <= adj_sec1- 1'b1;
- if(adj_sec1 == 4'd0) begin
- adj_sec1 <= 4'd5;
- end
- end
- end
- end
- 2'b01: begin //分个位
- if(key_up) begin
- adj_min0 <= adj_min0 + 1'b1;
- if(adj_min0 == 4'd9) begin
- adj_min0 <= 4'd0;
- adj_min1 <= adj_min1 + 1'b1;
- if(adj_min1 == 4'd5) begin
- adj_min1 <= 4'd0;
- end
- end
- end
- else if(key_down) begin
- adj_min0 <= adj_min0 - 1'b1;
- if(adj_min0 == 4'd0) begin
- adj_min0 <= 4'd9;
- adj_min1 <= adj_min1- 1'b1;
- if(adj_min1 == 4'd0) begin
- adj_min1 <= 4'd5;
- end
- end
- end
- end
- 2'b10: begin //时个位
- if(key_up) begin
- adj_hour0 <= adj_hour0 + 1'b1;
- if(adj_hour0 == 4'd9) begin
- adj_hour0 <= 4'd0;
- adj_hour1 <= adj_hour1 + 1'b1;
- end
- if(adj_hour1 ==4'd2 && adj_hour0 == 4'd3) begin
- adj_hour1 <= 4'd0;
- adj_hour0 <= 4'd0;
- end
- end
- if(key_down) begin
- adj_hour0 <= adj_hour0 - 1'b1;
- if(adj_hour0 == 4'd0) begin
- adj_hour0 <= 4'd9;
- adj_hour1 <= adj_hour1 - 1;
- end
- if(adj_hour1 ==4'd0 && adj_hour0 == 4'd0) begin
- adj_hour1 <= 4'd2;
- adj_hour0 <= 4'd3;
- end
- end
- end
- default: begin
- adj_sec0 <= 4'dx;
- adj_sec1 <= 4'dx;
- adj_min0 <= 4'dx;
- adj_min1 <= 4'dx;
- adj_hour0 <= 4'dx;
- adj_hour1 <= 4'dx;
- end
- endcase
- end
- else begin
- {adj_hour1, adj_hour0, adj_min1, adj_min0, adj_sec1, adj_sec0} <= time_num; //将当前时间赋给调节变量
- end
- end
- //-------------------- 输出 ---------------
- assign adjust_time_num = {adj_hour1, adj_hour0, adj_min1, adj_min0, adj_sec1, adj_sec0};
- assign adjust_clock_num = {clock_hour1, clock_hour0, clock_min1, clock_min0};
- endmodule
- module alarm_music(
- input clk,
- input rst_n,
- input [15:0] adjust_clock_num, //闹钟调整值,只有小时和分钟
- input [23:0] time_num,
- input key_alarm,
- input time_led,
- output beep
- );
- //-------- 闹钟使能逻辑 --------------------------
- reg flag_en;
- reg [7:0] state;
- always@(posedge clk, negedge rst_n) begin
- if(!rst_n)
- flag_en <= 1'b0;
- else if(({adjust_clock_num,8'd0} == time_num)&&key_alarm) //闹钟时间到
- flag_en <= 1'b1;
- else if(state == 8'd191||!key_alarm) //一首音乐结束或关闭闹钟开关
- flag_en <= 1'b0;
- else
- flag_en <= flag_en;
- end
- //--------- 整点报时使能逻辑 ---------------
- wire flag_en1;
- assign flag_en1=(time_led&&!flag_en);//闹钟响起时不再整点报时
- //--------------- 音乐 -------------------------
- reg beep_r;
- reg [16:0] count, count_end;
- reg [23:0] count1;
- localparam C_1 = 17'd95_565,
- C_2 = 17'd85_149,
- C_3 = 17'd75_849,
- C_4 = 17'd71_592,
- C_5 = 17'd63_775,
- C_6 = 17'd56_818,
- C_7 = 17'd50_627,
- C_0 = 17'd55_555;
- localparam TIME = 6_250_000; //6_250_000每个音的长短(125ms)
- assign beep = beep_r;
- always@(posedge clk, negedge rst_n) begin
- if(!rst_n) begin
- count <= 17'h0;
- beep_r <= 1'b1;
- end
- else if(flag_en||flag_en1) begin //========
- count <= count + 1'b1;
- if(count == count_end) begin
- count <= 17'h0;
- if(count_end!=17'd55_555) beep_r <= !beep_r;
- end
- end
- else begin
- count <= 17'h0;
- beep_r <= 1'b1;
- end
- end
- always@(posedge clk, negedge rst_n) begin
- if(!rst_n) begin
- count1 <= 24'd0;
- state <= 8'd0;
- end
- else if(flag_en) begin
- if(count1 < TIME)
- count1 <= count1 + 1'b1;
- else begin
- count1 <= 24'd0;
- if(state >= 8'd191)
- state <= 8'd0;
- else
- state <= state + 1'b1;
- end
- end
- else if(flag_en1) begin //==================
- if(count1 < TIME)
- count1 <= count1 + 1'b1;
- else begin
- count1 <= 24'd0;
- if(state >= 8'd207||state < 8'd192)
- state <= 8'd192;
- else
- state <= state + 1'b1;
- end
- end
- else begin
- count1 <= 24'd0;
- state <= 8'd0;
- end
- end
- always@(state) begin
- case(state)
- 8'd0,8'd1,8'd2: count_end = C_1;
- 8'd3:count_end = C_0;
- 8'd4,8'd5,8'd6: count_end = C_1;
- 8'd7:count_end = C_0;
- 8'd8,8'd9,8'd10: count_end = C_5;
- 8'd11:count_end = C_0;
- 8'd12,8'd13,8'd14: count_end = C_5;
- 8'd15:count_end = C_0;
-
- 8'd16,8'd17,8'd18: count_end = C_6;
- 8'd19:count_end = C_0;
- 8'd20,8'd21,8'd22: count_end = C_6;
- 8'd23:count_end = C_0;
- 8'd24,8'd25,8'd26,8'd27: count_end = C_5;
- 8'd28,8'd29,8'd30: count_end = C_5;
- 8'd31:count_end = C_0;
-
- 8'd32,8'd33,8'd34: count_end = C_4;
- 8'd35:count_end = C_0;
- 8'd36,8'd37,8'd38: count_end = C_4;
- 8'd39:count_end = C_0;
- 8'd40,8'd41,8'd42: count_end = C_3;
- 8'd43:count_end = C_0;
- 8'd44,8'd45,8'd46: count_end = C_3;
- 8'd47:count_end = C_0;
-
- 8'd48,8'd49,8'd50: count_end = C_2;
- 8'd51:count_end = C_0;
- 8'd52,8'd53,8'd54: count_end = C_2;
- 8'd55:count_end = C_0;
- 8'd56,8'd57,8'd58,8'd59: count_end = C_1;
- 8'd60,8'd61,8'd62: count_end = C_1;
- 8'd63:count_end = C_0;
-
- 8'd64,8'd65,8'd66: count_end = C_5;
- 8'd67:count_end = C_0;
- 8'd68,8'd69,8'd70: count_end = C_5;
- 8'd71:count_end = C_0;
- 8'd72,8'd73,8'd74: count_end = C_4;
- 8'd75:count_end = C_0;
- 8'd76,8'd77,8'd78: count_end = C_4;
- 8'd79:count_end = C_0;
-
- 8'd80,8'd81,8'd82: count_end = C_3;
- 8'd83:count_end = C_0;
- 8'd84,8'd85,8'd86: count_end = C_3;
- 8'd87:count_end = C_0;
- 8'd88,8'd89,8'd90,8'd91: count_end = C_2;
- 8'd92,8'd93,8'd94: count_end = C_2;
- 8'd95:count_end = C_0;
-
- 8'd96,8'd97,8'd98: count_end = C_5;
- 8'd99:count_end = C_0;
- 8'd100,8'd101,8'd102: count_end = C_5;
- 8'd103:count_end = C_0;
- 8'd104,8'd105,8'd106: count_end = C_4;
- 8'd107:count_end = C_0;
- 8'd108,8'd109,8'd110: count_end = C_4;
- 8'd111:count_end = C_0;
-
- 8'd112,8'd113,8'd114: count_end = C_3;
- 8'd115:count_end = C_0;
- 8'd116,8'd117,8'd118: count_end = C_3;
- 8'd119:count_end = C_0;
- 8'd120,8'd121,8'd122,8'd123: count_end = C_2;
- 8'd124,8'd125,8'd126: count_end = C_2;
- 8'd127:count_end = C_0;
-
- 8'd128,8'd129,8'd130: count_end = C_1;
- 8'd131:count_end = C_0;
- 8'd132,8'd133,8'd134: count_end = C_1;
- 8'd135:count_end = C_0;
- 8'd136,8'd137,8'd138: count_end = C_5;
- 8'd139:count_end = C_0;
- 8'd140,8'd141,8'd142: count_end = C_5;
- 8'd143:count_end = C_0;
-
- 8'd144,8'd145,8'd146: count_end = C_6;
- 8'd147:count_end = C_0;
- 8'd148,8'd149,8'd150: count_end = C_6;
- 8'd151:count_end = C_0;
- 8'd152,8'd153,8'd154,8'd155: count_end = C_5;
- 8'd156,8'd157,8'd158: count_end = C_5;
- 8'd159:count_end = C_0;
-
- 8'd160,8'd161,8'd162: count_end = C_4;
- 8'd163:count_end = C_0;
- 8'd164,8'd165,8'd166: count_end = C_4;
- 8'd167:count_end = C_0;
- 8'd168,8'd169,8'd170: count_end = C_3;
- 8'd171:count_end = C_0;
- 8'd172,8'd173,8'd174: count_end = C_3;
- 8'd175:count_end = C_0;
-
- 8'd176,8'd177,8'd178: count_end = C_2;
- 8'd179:count_end = C_0;
- 8'd180,8'd181,8'd182: count_end = C_2;
- 8'd183:count_end = C_0;
- 8'd184,8'd185,8'd186,8'd187: count_end = C_1;
- 8'd188,8'd189,8'd190: count_end = C_1;
- 8'd191:count_end = C_0;
- //===================整点报时音乐=====================
- 8'd192: count_end = C_7;
- 8'd193:count_end = C_0;
- 8'd194: count_end = C_7;
- 8'd195:count_end = C_0;
- 8'd196: count_end = C_7;
- 8'd197:count_end = C_0;
- 8'd198: count_end = C_7;
- 8'd199:count_end = C_0;
- 8'd200,8'd201,8'd202,8'd203,
- 8'd204,8'd205,8'd206,8'd207: count_end = C_1;
-
- default: count_end = 17'hxxxxx;
- endcase
- end
- endmodule
- module stop_watch(
- input clk,
- input rst_n,
- input [1:0] model,
- input pause, //秒表暂停/开始
- input clear, //秒表清除
- output [23:0] stop_watch_num //输出显示
- );
- //---------------------- 10ms上升沿 ----------------------
- wire clk_10ms;
- reg clk_10ms_reg1, clk_10ms_reg2;
- wire pos_10ms;
- clk_div #(.CNT_MAX(250000)) clk_div_10ms( //250000仿真参数250
- .clk_in (clk),
- .rst_n (rst_n),
- .clk_out (clk_10ms)
- );
- always@(posedge clk, negedge rst_n) begin
- if(!rst_n) begin
- clk_10ms_reg1 <= 1'b0;
- clk_10ms_reg2 <= 1'b0;
- end
- else begin
- clk_10ms_reg1 <= clk_10ms;
- clk_10ms_reg2 <= clk_10ms_reg1;
- end
- end
- assign pos_10ms = clk_10ms_reg1 & (~clk_10ms_reg2);
- //----------------------- 10ms_计数 ------------------------
- reg [3:0] cnt_ms0;
- reg [3:0] cnt_ms1;
- reg [3:0] cnt_s0;
- reg [3:0] cnt_s1;
- reg [3:0] cnt_m0;
- reg [3:0] cnt_m1;
- always@(posedge clk, negedge rst_n) begin
- if(!rst_n) begin //异步复位
- cnt_ms0 <= 4'd0;
- cnt_ms1 <= 4'd0;
- cnt_s0 <= 4'd0;
- cnt_s1 <= 4'd0;
- cnt_m0 <= 4'd0;
- cnt_m1 <= 4'd0;
- end
- else if(clear) begin //同步清零
- cnt_ms0 <= 4'd0;
- cnt_ms1 <= 4'd0;
- cnt_s0 <= 4'd0;
- cnt_s1 <= 4'd0;
- cnt_m0 <= 4'd0;
- cnt_m1 <= 4'd0;
- end
- else if(pos_10ms) begin
- if(model == 2'b10) begin //秒表模式
- if(pause) begin //开始
- cnt_ms0 <= cnt_ms0 + 1'b1;
- if(cnt_ms0 == 4'd9) begin
- cnt_ms0 <= 4'd0;
- cnt_ms1 <= cnt_ms1 + 1'b1;
- if(cnt_ms1 == 4'd9) begin //99, 1s时间到
- cnt_ms1 <= 4'd0;
- cnt_s0 <= cnt_s0 + 1'b1;
- if(cnt_s0 == 4'd9) begin
- cnt_s0 <= 4'd0;
- cnt_s1 <= cnt_s1 + 1'b1;
- if(cnt_s1 == 4'd5) begin //59s
- cnt_s1 <= 4'd0;
- cnt_m0 <= cnt_m0 + 1'b1;
- if(cnt_m0 == 4'd9) begin
- cnt_m0 <= 4'd0;
- cnt_m1 <= cnt_m1 + 1'b1;
- end
- end
- end
- end
- end
- end
- end
- end
- else if(cnt_m1==4'd10) begin //上限
- cnt_ms0 <= 4'd0;
- cnt_ms1 <= 4'd0;
- cnt_s0 <= 4'd0;
- cnt_s1 <= 4'd0;
- cnt_m0 <= 4'd0;
- cnt_m1 <= 4'd0;
- end
- else begin
- cnt_ms0 <= cnt_ms0;
- cnt_ms1 <= cnt_ms1;
- cnt_s0 <= cnt_s0;
- cnt_s1 <= cnt_s1;
- cnt_m0 <= cnt_m0;
- cnt_m1 <= cnt_m1;
- end
- end
- //--------------------------- 输出 ------------------
- assign stop_watch_num = {cnt_m1, cnt_m0, cnt_s1, cnt_s0, cnt_ms1, cnt_ms0};
- endmodule
- //---------------------数码管显示-------------------------------------------------
- module led_seg7_display(
- input clk,
- input rst_n,
- input [1:0] model,
- input [23:0] time_num, // 时钟数据
- input [23:0] adjust_time_num, // 调整时钟数据
- input [15:0] adjust_clock_num,// 调整闹钟数据
- input [23:0] stop_watch_num, // 秒表
- output [5:0] sel, // 数码管位选(选择当前要显示的数码管)
- output reg [6:0] seg // 数码管段选(当前要显示的内容)
- );
- //---------------- 显示数据选择 ----------------------
- reg [23:0] show_num;
- always@(posedge clk, negedge rst_n) begin
- if(!rst_n)
- show_num <= 24'h0;
- else begin
- if(model == 2'b00) begin //常规显示
- show_num <= time_num;
- end
- else if(model == 2'b01) //闹钟显示
- show_num <= {adjust_clock_num, 8'b00000000}; //闹钟只有小时和分钟
- else if(model == 2'b10) //秒表显示
- show_num <= stop_watch_num;
- else begin //调整时间
- show_num <= adjust_time_num;
- end
- end
- end
- //--------------------- 数码管显示逻辑 ------------------------
- wire clk_1ms; //数码管扫描周期1ms
- clk_div #(.CNT_MAX(100000)) clk_div_1ms( //100000为了缩短仿真时间,参数设100
- .clk_in (clk),
- .rst_n (rst_n),
- .clk_out (clk_1ms)
- );
- reg [5:0]sel_r; //位选缓存
- reg [3:0]data_tmp; //数据缓存
- always@(posedge clk_1ms or negedge rst_n)
- if(!rst_n)
- sel_r <= 6'b0000_01;
- else if(sel_r == 6'b1000_00)
- sel_r <= 6'b0000_01;
- else
- sel_r <= sel_r << 1;
- always@(*)
- case(sel_r)
- 8'b0000_01:data_tmp = show_num[3:0];
- 8'b0000_10:data_tmp = show_num[7:4];
- 8'b0001_00:data_tmp = show_num[11:8];
- 8'b0010_00:data_tmp = show_num[15:12];
- 8'b0100_00:data_tmp = show_num[19:16];
- 8'b1000_00:data_tmp = show_num[23:20];
- default: data_tmp = 4'b0000;
- endcase
- always@(*)
- case(data_tmp)
- 4'd0:seg = 7'b1111110;
- 4'd1:seg = 7'b0110000;
- 4'd2:seg = 7'b1101101;
- 4'd3:seg = 7'b1111001;
- 4'd4:seg = 7'b0110011;
- 4'd5:seg = 7'b1011011;
- 4'd6:seg = 7'b1011111;
- 4'd7:seg = 7'b1110000;
- 4'd8:seg = 7'b1111111;
- 4'd9:seg = 7'b1111011;
- default: seg = 7'b1111111;
- endcase
- assign sel = sel_r;
- endmodule
- //modelsim仿真
- `timescale 10ns/ 10ns
- module text_CourseDesign_513();
- reg clk;
- reg rst_n;
- reg [6:1] key_in;
- reg key_input;
- reg key_alarm;
- wire [5:0] sel;
- wire [7:6] sel_0;
- wire [6:0] seg;
- wire beep;
- wire [3:0] model_led;
- CourseDesign_513 h(
- .clk(clk), //50MHz
- .rst_n(rst_n), //初始化
- .key_in(key_in), //按键输入
- .key_input(key_input), //设置时间的确认按键
- .key_alarm(key_alarm), //闹钟开关
- .sel(sel), //数码管位选
- .sel_0(sel_0), //数码管不显示
- .seg(seg), //数码管段选
- .beep(beep), //闹钟音乐
- .model_led(model_led) //模式led
- );
- initial
- begin
- clk = 1'b0;
- rst_n=1'b0;
- key_in=6'b000000;
- key_input=1'b0;
- key_alarm=1'b0;
- #50_000 rst_n=1'b1;//初始化结束
- #1_000_000 key_in=6'b000001;//切换闹钟模式
- #10_000 key_in=6'b000000;
- #10_000 key_in=6'b000001;//切换秒表模式
- #10_000 key_in=6'b000000;
- #50_000 key_in=6'b010000;//开始计时
- #10_000 key_in=6'b000000;
- #500_000 key_in=6'b010000;//暂停
- #10_000 key_in=6'b000000;
- #50_000 key_in=6'b100000;//清零
- #10_000 key_in=6'b000000;
- #50_000 key_in=6'b000001;//切换调时模式
- #10_000 key_in=6'b000000;
- #10_000 key_in=6'b000010;//调位置
- #10_000 key_in=6'b000000;
- #10_000 key_in=6'b001000;//加1
- #10_000 key_in=6'b000000;
- #10_000 key_in=6'b001000;//加2
- #10_000 key_in=6'b000000;
- #10_000 key_in=6'b001000;//加3
- #10_000 key_in=6'b000000;
- #10_000 key_in=6'b001000;//加4
- #10_000 key_in=6'b000000;
- #10_000 key_in=6'b001000;//加5
- #10_000 key_in=6'b000000;
- #10_000 key_input=1'b1;key_in=6'b000001;//调时确认
- #10000 key_input=1'b0;key_in=6'b000000;
- end
- always #1 clk = ~clk;
- endmodule
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。