目录

  • 原理
  • 实现

原理

数字时钟:我这里实现的是数码管显示,外加设置时间功能和闹钟功能,闹钟就是蜂鸣器,没有其他的功能。
状态机:这里就不具体介绍了,上一篇已经介绍过了。

实现

设计:
1)按键消抖模块
2)控制模块(实现状态机,产生数码管显示数据,输出蜂鸣器信号,主要模块)
3)数码管驱动模块
4)蜂鸣器驱动模块
按键消抖就不粘贴复制了,上一篇博客很清楚了,
驱动
控制模块
别看代码多,大部分粘贴复制再改下信号名
我认为逻辑还是比较清晰了
分三个功能,正常显示时间(时间计数器),设置时间(再定义一组寄存器,结构和时间计数器一样,就是加1条件不太一样,基本是用按键控制的),设置闹钟(同设置时间一样)

module control(input               clk                    ,input               rst_n                  ,input   [2:0]       key                    ,output  [23:0]      time_data              ,output              alarm_clk_flag         ,output  [5:0]       shan_shuo
);
localparam TIME_1S = 50_000_000;
localparam IDLE = 3'b001;
localparam SET_TIME  = 3'b010;
localparam SET_ALARM  = 3'b100;wire idle2set_time;
wire idle2set_alarm;
wire set_time2idle;
wire set_alarm2idle;
reg [2:0] state_c;
reg [2:0] state_n;reg [5:0] shanshuo_r;//闪烁标志,选中位0/1不停变换reg set_time_flag;//设置时间标志
reg set_alarm_flag;//设置闹钟标志reg [23:0] time_data_r;reg [25:0] cnt_1s;//1s计数器
wire add_cnt_1s;
wire end_cnt_1s;reg [3:0] cnt0;//s个位计数器
wire add_cnt0;
wire end_cnt0;reg [3:0] cnt1;//s十位计数器
wire add_cnt1;
wire end_cnt1;reg [3:0] cnt2;//m个位计数器
wire add_cnt2;
wire end_cnt2;reg [3:0] cnt3;//m十位计数器
wire add_cnt3;
wire end_cnt3;reg [3:0] cnt4;//h个位计数器
wire add_cnt4;
wire end_cnt4;reg [3:0] cnt5;//h十位计数器
wire add_cnt5;
wire end_cnt5;//设置时间寄存器
reg [3:0] set_time_cnt0;//s个位计数器reg [3:0] set_time_cnt1;//s十位计数器reg [3:0] set_time_cnt2;//m个位计数器reg [3:0] set_time_cnt3;//m十位计数器reg [3:0] set_time_cnt4;//h个位计数器reg [3:0] set_time_cnt5;//h十位计数器reg [2:0] key_sel_time;//设置时间片选记录
wire add_key_sel_time;
wire end_key_sel_time;reg [2:0] key_sel_alarm;//设置闹钟片选记录
wire add_key_sel_alarm;
wire end_key_sel_alarm;//设置闹钟寄存器
reg [23:0] alarm;//保存闹钟数据
reg [3:0] set_alarm_cnt0;//s个位计数器reg [3:0] set_alarm_cnt1;//s十位计数器reg [3:0] set_alarm_cnt2;//m个位计数器reg [3:0] set_alarm_cnt3;//m十位计数器reg [3:0] set_alarm_cnt4;//h个位计数器reg [3:0] set_alarm_cnt5;//h十位计数器always@(posedge clk or negedge rst_n)beginif(!rst_n)beginstate_c <= IDLE;endelse beginstate_c <= state_n;end
endalways @(*) begincase(state_c)IDLE:beginif(idle2set_time)beginstate_n <= SET_TIME;endelse if(idle2set_alarm)beginstate_n <= SET_ALARM;endelse beginstate_n <= state_c;endendSET_TIME:beginif(set_time2idle)beginstate_n <= IDLE;endelse beginstate_n <= state_c;endendSET_ALARM:beginif(set_alarm2idle)beginstate_n <= IDLE;endelse beginstate_n <= state_c;endenddefault:state_n = state_c;endcase
endassign idle2set_time    = (state_c == IDLE)     && (set_time_flag);
assign idle2set_alarm   = (state_c == IDLE)     && (set_alarm_flag);
assign set_time2idle    = (state_c == SET_TIME) && (!set_time_flag);
assign set_alarm2idle   = (state_c == SET_ALARM)&& (!set_alarm_flag);//1s计数器
always@(posedge clk or negedge rst_n)beginif(!rst_n)begincnt_1s <= 26'b0;endelse if(add_cnt_1s)beginif(end_cnt_1s)begincnt_1s <= 26'b0;endelse begincnt_1s <= cnt_1s + 1'b1;endend
end
assign add_cnt_1s = 1'b1;
assign end_cnt_1s = add_cnt_1s && (cnt_1s == TIME_1S - 1);
//s个位计数器
always@(posedge clk or negedge rst_n)beginif(!rst_n)begincnt0 <= 4'b0;endelse if(add_cnt0)beginif(end_cnt0)begincnt0 <= 4'b0;endelse begincnt0 <= cnt0 + 1'b1;endendelse if(set_time2idle)begincnt0 <= set_time_cnt0;end
end
assign add_cnt0 = end_cnt_1s;
assign end_cnt0 = add_cnt0 && (cnt0 == 10 - 1);
//s十位计数器
always@(posedge clk or negedge rst_n)beginif(!rst_n)begincnt1 <= 4'b0;endelse if(add_cnt1)beginif(end_cnt1)begincnt1 <= 4'b0;endelse begincnt1 <= cnt1 + 1'b1;endendelse if(set_time2idle)begincnt1 <= set_time_cnt1;end
end
assign add_cnt1 = end_cnt0;
assign end_cnt1 = add_cnt1 && (cnt1 == 6 - 1);
//m个位计数器
always@(posedge clk or negedge rst_n)beginif(!rst_n)begincnt2 <= 4'b0;endelse if(add_cnt2)beginif(end_cnt2)begincnt2 <= 4'b0;endelse begincnt2 <= cnt2 + 1'b1;endendelse if(set_time2idle)begincnt2 <= set_time_cnt2;end
end
assign add_cnt2 = end_cnt1;
assign end_cnt2 = add_cnt2 && (cnt2 == 10 - 1);
//m十位计数器
always@(posedge clk or negedge rst_n)beginif(!rst_n)begincnt3 <= 4'b0;endelse if(add_cnt3)beginif(end_cnt3)begincnt3 <= 4'b0;endelse begincnt3 <= cnt3 + 1'b1;endendelse if(set_time2idle)begincnt3 <= set_time_cnt3;end
end
assign add_cnt3 = end_cnt2;
assign end_cnt3 = add_cnt3 && (cnt3 == 6 - 1);
//h个位计数器
always@(posedge clk or negedge rst_n)beginif(!rst_n)begincnt4 <= 4'b0;endelse if(add_cnt4)beginif(end_cnt4)begincnt4 <= 4'b0;endelse begincnt4 <= cnt4 + 1'b1;endendelse if(set_time2idle)begincnt4 <= set_time_cnt4;end
end
assign add_cnt4 = end_cnt3;
assign end_cnt4 = add_cnt4 && (cnt4 == ((cnt5 == 2)?(4 - 1):(10 - 1)));
//h十位计数器
always@(posedge clk or negedge rst_n)beginif(!rst_n)begincnt5 <= 4'b0;endelse if(add_cnt5)beginif(end_cnt5)begincnt5 <= 4'b0;endelse begincnt5 <= cnt5 + 1'b1;endendelse if(set_time2idle)begincnt5 <= set_time_cnt5;end
end
assign add_cnt5 = end_cnt4;
assign end_cnt5 = add_cnt5 && (cnt5 == 2);//选中位反转
always@(posedge clk or negedge rst_n)beginif(!rst_n)beginshanshuo_r <= 0;endelse if(state_c == IDLE)beginshanshuo_r <= 6'b000_000;endelse if(state_c == SET_TIME)begincase(key_sel_time)3'd0:beginif(end_cnt0)beginshanshuo_r[5]<=1;shanshuo_r[0] <= ~shanshuo_r[0];endend3'd1:beginif(end_cnt0)beginshanshuo_r[0]<=1;shanshuo_r[1] <= ~shanshuo_r[1];endend3'd2:beginif(end_cnt0)beginshanshuo_r[1]<=1;shanshuo_r[2] <= ~shanshuo_r[2];endend3'd3:beginif(end_cnt0)beginshanshuo_r[2]<=1;shanshuo_r[3] <= ~shanshuo_r[3];endend3'd4:beginif(end_cnt0)beginshanshuo_r[3]<=1;shanshuo_r[4] <= ~shanshuo_r[4];endend3'd5:beginif(end_cnt0)beginshanshuo_r[4]<=1;shanshuo_r[5] <= ~shanshuo_r[5];endenddefault:shanshuo_r <= shanshuo_r;endcaseendelse if(state_c == SET_ALARM)begincase(key_sel_alarm)3'd0:beginif(cbt_1s)beginshanshuo_r[5]<=1;shanshuo_r[0] <= ~shanshuo_r[0];endend3'd1:beginif(cbt_1s)beginshanshuo_r[0]<=1;shanshuo_r[1] <= ~shanshuo_r[1];endend3'd2:beginif(cbt_1s)beginshanshuo_r[1]<=1;shanshuo_r[2] <= ~shanshuo_r[2];endend3'd3:beginif(cbt_1s)beginshanshuo_r[2]<=1;shanshuo_r[3] <= ~shanshuo_r[3];endend3'd4:beginif(cbt_1s)beginshanshuo_r[3]<=1;shanshuo_r[4] <= ~shanshuo_r[4];endend3'd5:beginif(cbt_1s)beginshanshuo_r[4]<=1;shanshuo_r[5] <= ~shanshuo_r[5];endenddefault:shanshuo_r <= shanshuo_r;endcaseend
end
assign shan_shuo = shanshuo_r;//-----------------------------设置时间------------------------------------------------------------------------//时间设置标志
always@(posedge clk or negedge rst_n)beginif(!rst_n)beginset_time_flag <= 1'b0;endelse if((state_c == IDLE) && key[0])beginset_time_flag <= 1'b1;endelse if((state_c == SET_TIME) && key[0])beginset_time_flag <= 1'b0;end
end
//时间设置寄存器赋值
//s个位
always@(posedge clk or negedge rst_n)beginif(!rst_n)beginset_time_cnt0 <= 0;endelse if(idle2set_time)beginset_time_cnt0 <= cnt0;endelse if((state_c == SET_TIME) && key[1] && key_sel_time == 3'd0)beginif(set_time_cnt0 == 10 -1)beginset_time_cnt0 <= 0;endelse beginset_time_cnt0 <= set_time_cnt0 + 1;end     end
end
//s十位
always@(posedge clk or negedge rst_n)beginif(!rst_n)beginset_time_cnt1 <= 0;endelse if(idle2set_time)beginset_time_cnt1 <= cnt1;endelse if((state_c == SET_TIME) && key[1] && key_sel_time == 3'd1)beginif(set_time_cnt1 == 6 - 1)beginset_time_cnt1 <= 0;endelse beginset_time_cnt1 <= set_time_cnt1 + 1;endend
end
//m个位
always@(posedge clk or negedge rst_n)beginif(!rst_n)beginset_time_cnt2 <= 0;endelse if(idle2set_time)beginset_time_cnt2 <= cnt2;endelse if((state_c == SET_TIME) && key[1] && key_sel_time == 3'd2)beginif(set_time_cnt2 == 10 - 1)beginset_time_cnt2 <= 0;endelse beginset_time_cnt2 <= set_time_cnt2 + 1;end   end
end
//m十位
always@(posedge clk or negedge rst_n)beginif(!rst_n)beginset_time_cnt3 <= 0;endelse if(idle2set_time)beginset_time_cnt3 <= cnt3;endelse if((state_c == SET_TIME) && key[1] && key_sel_time == 3'd3)beginif(set_time_cnt3 == 6 - 1)beginset_time_cnt3 <= 0;endelse beginset_time_cnt3 <= set_time_cnt3 + 1;end end
end
//h个位
always@(posedge clk or negedge rst_n)beginif(!rst_n)beginset_time_cnt4 <= 0;endelse if(idle2set_time)beginset_time_cnt4 <= cnt4;endelse if((state_c == SET_TIME) && key[1] && key_sel_time == 3'd4)beginif(set_time_cnt4 == ((set_time_cnt5 == 2)?(4 - 1):(10 - 1)))beginset_time_cnt4 <= 0;endelse beginset_time_cnt4 <= set_time_cnt4 + 1;end  end
end
//h十位
always@(posedge clk or negedge rst_n)beginif(!rst_n)beginset_time_cnt5 <= 0;endelse if(idle2set_time)beginset_time_cnt5 <= cnt5;endelse if((state_c == SET_TIME) && key[1] && key_sel_time == 3'd5)beginif(set_time_cnt5 == ((set_time_cnt4<3)?1:2))beginset_time_cnt5 <= 0;endelse beginset_time_cnt5 <= set_time_cnt5 + 1;end end
end
//设置时间片选计数器
always@(posedge clk or negedge rst_n)beginif(!rst_n)beginkey_sel_time <= 0;endelse if(add_key_sel_time)beginif(end_key_sel_time)beginkey_sel_time <= 0;endelse beginkey_sel_time <= key_sel_time + 1;endend
end
assign add_key_sel_time = key[2] && (state_c == SET_TIME);
assign end_key_sel_time = add_key_sel_time && (key_sel_time == 6 - 1);//---------------------------设置闹钟------------------------------------------------------------------//闹钟设置标志
always@(posedge clk or negedge rst_n)beginif(!rst_n)beginset_alarm_flag <= 1'b0;endelse if((state_c == IDLE) && key[1])beginset_alarm_flag <= 1'b1;endelse if((state_c == SET_ALARM) && key[1])beginset_alarm_flag <= 1'b0;end
end//设置闹钟片选计数器
always@(posedge clk or negedge rst_n)beginif(!rst_n)beginkey_sel_alarm <= 0;endelse if(add_key_sel_alarm)beginif(end_key_sel_alarm)beginkey_sel_alarm <= 0;endelse beginkey_sel_alarm <= key_sel_alarm + 1;endend
end
assign add_key_sel_alarm = key[2] && (state_c == SET_ALARM);
assign end_key_sel_alarm = add_key_sel_alarm && (key_sel_alarm == 6 - 1);
//s个位
always@(posedge clk or negedge rst_n)beginif(!rst_n)beginset_alarm_cnt0 <= 0;endelse if(idle2set_alarm)beginset_alarm_cnt0 <= cnt0;endelse if((state_c == SET_ALARM) && key[0] && key_sel_alarm == 3'd0)beginif(set_alarm_cnt0 == 10 -1)beginset_alarm_cnt0 <= 0;endelse beginset_alarm_cnt0 <= set_alarm_cnt0 + 1;end end
end
//s十位
always@(posedge clk or negedge rst_n)beginif(!rst_n)beginset_alarm_cnt1 <= 0;endelse if(idle2set_alarm)beginset_alarm_cnt1 <= cnt1;endelse if((state_c == SET_ALARM) && key[0] && key_sel_alarm == 3'd1)beginif(set_alarm_cnt1 == 6 -1)beginset_alarm_cnt1 <= 0;endelse beginset_alarm_cnt1 <= set_alarm_cnt1 + 1;end  end
end
//m个位
always@(posedge clk or negedge rst_n)beginif(!rst_n)beginset_alarm_cnt2 <= 0;endelse if(idle2set_alarm)beginset_alarm_cnt2 <= cnt2;endelse if((state_c == SET_ALARM) && key[0] && key_sel_alarm == 3'd2)beginif(set_alarm_cnt2 == 10 -1)beginset_alarm_cnt2 <= 0;endelse beginset_alarm_cnt2 <= set_alarm_cnt2 + 1;endend
end
//m十位
always@(posedge clk or negedge rst_n)beginif(!rst_n)beginset_alarm_cnt3 <= 0;endelse if(idle2set_alarm)beginset_alarm_cnt3 <= cnt3;endelse if((state_c == SET_ALARM) && key[0] && key_sel_alarm == 3'd3)beginif(set_alarm_cnt3 == 6 -1)beginset_alarm_cnt3 <= 0;endelse beginset_alarm_cnt3 <= set_alarm_cnt3 + 1;endend
end
//h个位
always@(posedge clk or negedge rst_n)beginif(!rst_n)beginset_alarm_cnt4 <= 0;endelse if(idle2set_alarm)beginset_alarm_cnt4 <= cnt4;endelse if((state_c == SET_ALARM) && key[0] && key_sel_alarm == 3'd4)beginif(set_alarm_cnt4 == ((set_alarm_cnt5 == 2)?(4 - 1):(10 - 1)))beginset_alarm_cnt4 <= 0;endelse beginset_alarm_cnt4 <= set_alarm_cnt4 + 1;endend
end
//h十位
always@(posedge clk or negedge rst_n)beginif(!rst_n)beginset_alarm_cnt5 <= 0;endelse if(idle2set_alarm)beginset_alarm_cnt5 <= cnt5;endelse if((state_c == SET_ALARM) && key[0] && key_sel_alarm == 3'd5)beginif(set_alarm_cnt5 == ((set_alarm_cnt5 > 3)?1:2)beginset_alarm_cnt5 <= 0;endelse beginset_alarm_cnt5 <= set_alarm_cnt5 + 1;endend
end//保存闹钟
always@(posedge clk or negedge rst_n)beginif(!rst_n)beginalarm <= 0;endelse if(set_alarm2idle)beginalarm <= {set_alarm_cnt5,set_alarm_cnt4,set_alarm_cnt3,set_alarm_cnt2,set_alarm_cnt1,set_alarm_cnt0};end
end//数码管显示
always@(posedge clk or negedge rst_n)beginif(!rst_n)begintime_data_r <= 0;endelse begincase(state_c)IDLE:     time_data_r <= {cnt5,cnt4,cnt3,cnt2,cnt1,cnt0};  SET_TIME: time_data_r <= {set_time_cnt5,set_time_cnt4,set_time_cnt3,set_time_cnt2,set_time_cnt1,set_time_cnt0};SET_ALARM:time_data_r <= {set_alarm_cnt5,set_alarm_cnt4,set_alarm_cnt3,set_alarm_cnt2,set_alarm_cnt1,set_alarm_cnt0};default:  time_data_r <= {cnt5,cnt4,cnt3,cnt2,cnt1,cnt0};endcaseend
end
assign time_data = time_data_r;//闹钟标志信号
assign alarm_clk_flag = ((state_c == IDLE) && (alarm == {cnt5,cnt4,cnt3,cnt2,cnt1,cnt0}));endmodule

数码管驱动
和正常的驱动就多了个闪烁信号,可以使选中位闪烁

module seg_driver(input               clk     ,input               rst_n   ,input      [23:0]   din     ,output reg [5:0]    sel     ,output reg [7:0]    dig     ,     input      [5:0]    shan_shuo
);parameter TIME_10MS = 25_000;
parameter TIME_500MS = 25_000_000;
//共阳极数码管  低电平点亮localparam  ZERO     = 7'b100_0000,ONE      = 7'b111_1001,TWO      = 7'b010_0100,   THREE    = 7'b011_0000,   FOUR     = 7'b001_1001,FIVE     = 7'b001_0010, SIX      = 7'b000_0010, SEVEN    = 7'b111_1000, EIGHT    = 7'b000_0000,NINE     = 7'b001_0000,OFF      = 7'b111_1111;//信号定义reg dot;reg [19:0] cnt;//扫描计数器
wire add_cnt;
wire end_cnt;reg [3:0] data;//根据片选信号选择高四位还是第四位//刷新频率计数器
always@(posedge clk or negedge rst_n)beginif(!rst_n)begincnt <= 0;endelse if(add_cnt)beginif(end_cnt)begincnt <= 0;endelse begincnt <= cnt + 1'b1;endend
end
assign add_cnt = 1'b1;
assign end_cnt = add_cnt && (cnt == TIME_10MS - 1);
//片选信号选择
always@(posedge clk or negedge rst_n)beginif(!rst_n)beginsel <= 6'b111_110;;endelse if(end_cnt)beginsel <= {sel[0],sel[5:1]};end
endalways @(posedge clk or negedge rst_n) beginif(!rst_n)begindata <= 4'b0;endelse begincase(sel)6'b111_110: begin data <= shan_shuo[0]? din [3:0]  :7'd10 ;dot <=  1'b1;end6'b111_101: begin data <= shan_shuo[1]? din [7:4]  :7'd10 ;dot <=  1'b1;end6'b111_011: begin data <= shan_shuo[2]? din [11:8] :7'd10 ;dot <=  1'b0;end6'b110_111: begin data <= shan_shuo[3]? din [15:12]:7'd10 ;dot <=  1'b1;end6'b101_111: begin data <= shan_shuo[4]? din [19:16]:7'd10 ;dot <=  1'b0;end6'b011_111: begin data <= shan_shuo[5]? din [23:20]:7'd10 ;dot <=  1'b1;enddefault: data <= din[3:0];endcase end
endalways @(*) begincase(data)4'd0:dig = {dot,ZERO }   ;4'd1:dig = {dot,ONE  }   ;4'd2:dig = {dot,TWO  }   ;4'd3:dig = {dot,THREE}   ;4'd4:dig = {dot,FOUR }   ;4'd5:dig = {dot,FIVE }   ;4'd6:dig = {dot,SIX  }   ;4'd7:dig = {dot,SEVEN}   ;4'd8:dig = {dot,EIGHT}   ;4'd9:dig = {dot,NINE }   ;4'd10:dig = {dot,OFF};default: dig = {dot,ZERO};endcase
end
endmodule

beep模块
这其实就是播放音乐的蜂鸣器程序加了个标志信号,当标志信号有效才令蜂鸣器响,另外控制蜂鸣器响的时间。

module beep(input       clk                ,input       rst_n              ,input       alarm_clk_flag     ,output      beep
);parameter M1 = 17'd95600;
parameter M2 = 17'd85150;
parameter M3 = 17'd75850;
parameter M4 = 17'd71600;
parameter M5 = 17'd63750;
parameter M6 = 17'd56800;
parameter M7 = 17'd50600;reg beep_r;
reg alarm_clk_flag_r;reg [16:0] cnt0;//音符周期计数器
wire add_cnt0;
wire end_cnt0;reg [8:0] cnt1;//音符重复次数计数器
wire add_cnt1;
wire end_cnt1;reg [4:0] cnt2;//音符总次数
wire add_cnt2;
wire end_cnt2;reg [1:0] cnt3;//音乐时间计数器 7次完结
wire add_cnt3;
wire end_cnt3;reg   [16:0] preset_note;//预设音符周期数
wire    [16:0] preset_duty;//占空比always@(posedge clk or negedge rst_n)beginif(!rst_n)beginalarm_clk_flag_r <= 1'b0;endelse if(alarm_clk_flag)beginalarm_clk_flag_r <= 1'b1;endelse if(cnt3 == 1)beginalarm_clk_flag_r <= 1'b0;end
end//音符周期计数
always@(posedge clk or negedge rst_n)beginif(!rst_n)begincnt0 <= 17'b0;endelse if(add_cnt0)beginif(end_cnt0)begincnt0 <= 17'b0;endelse begincnt0 <= cnt0 +1'b1;endend
end
assign add_cnt0 = 1'b1;
assign end_cnt0 = add_cnt0 && (cnt0 == preset_note - 1);//音符重复次数
always@(posedge clk or negedge rst_n)beginif(!rst_n)begincnt1 <= 9'b0;endelse if(add_cnt1)beginif(end_cnt1)begincnt1 <= 9'b0;endelse begincnt1 <= cnt1 +1'b1;endend
end
assign add_cnt1 = end_cnt0;
assign end_cnt1 = add_cnt1 && (cnt1 == 299);//音符总次数
always@(posedge clk or negedge rst_n)beginif(!rst_n)begincnt2 <= 5'b0;endelse if(add_cnt2)beginif(end_cnt2)begincnt2 <= 5'b0;endelse begincnt2 <= cnt2 +1'b1;endend
end
assign add_cnt2 = end_cnt1;
assign end_cnt2 = add_cnt2 && (cnt2 == 31);//音乐时间计数器 响3次
always@(posedge clk or negedge rst_n)beginif(!rst_n)begincnt3 <= 0;endelse if(add_cnt3)beginif(end_cnt3)begincnt3 <= 0;endelse begincnt3 <= cnt3 + 1;endend
end
assign add_cnt3 = end_cnt2;
assign end_cnt3 = add_cnt3 && (cnt3 == 4 - 1);//给音符周期赋值
always@(posedge clk or negedge rst_n)beginif(!rst_n)beginpreset_note <= 17'b0;endelse begincase(cnt2)6'd0    :   preset_note <= M1;6'd1    :   preset_note <= M2;6'd2    :   preset_note <= M3;6'd3    :   preset_note <= M1;6'd4    :   preset_note <= M1;6'd5    :   preset_note <= M2;6'd6    :   preset_note <= M3;6'd7    :   preset_note <= M1;6'd8    :   preset_note <= M3;6'd9    :   preset_note <= M4;6'd10   :   preset_note <= M5;6'd11   :   preset_note <= M3;6'd12   :   preset_note <= M4;6'd13   :   preset_note <= M5;6'd14   :   preset_note <= M5;6'd15   :   preset_note <= M6;6'd16   :   preset_note <= M5;6'd17   :   preset_note <= M4;6'd18   :   preset_note <= M3;6'd19   :   preset_note <= M1;6'd20   :   preset_note <= M5;6'd21   :   preset_note <= M6;6'd22   :   preset_note <= M5;6'd23   :   preset_note <= M4;6'd24   :   preset_note <= M3;6'd25   :   preset_note <= M1;6'd26   :   preset_note <= M2;6'd27   :   preset_note <= M5;6'd28   :   preset_note <= M1;6'd29   :   preset_note <= M2;6'd30   :   preset_note <= M5;6'd31   :   preset_note <= M1;default :   preset_note <= M1;endcaseend
end//给蜂鸣器赋值,并设定占空比
always@(posedge clk or negedge rst_n)beginif(!rst_n)beginbeep_r <= 1'b1;endelse if(cnt3 == 2'd1)beginbeep_r <= 1'b1;endelse if(alarm_clk_flag_r)beginif(cnt0 <= preset_duty)beginbeep_r <= 1'b0;endelse beginbeep_r <= 1'b1;endendelse begin     beep_r <= 1'b1;end
end
assign preset_duty = preset_note >> 1;
assign beep = beep_r;endmodule

顶层

module top(input             clk     ,input          rst_n   ,input   [2:0]   key_in  ,output  [5:0]   sel     ,output  [7:0]   dig     ,output          beep
);
wire [23:0] time_data;//显示数据
wire [2:0]  key_out;//按键消抖输出
wire alarm_clk_flag;//闹钟响标志
wire [5:0] shan_shuo;
seg_driver u_seg_driver(.clk     (clk       ),.rst_n   (rst_n     ),.din     (time_data ),.sel     (sel       ),.dig     (dig       ),.shan_shuo(shan_shuo)
);fsm_key_debounce # (.KEY_W(3)) u_fsm_key_debounce(.clk        (clk        ),.rst_n        (rst_n      ),.key_in       (key_in     ),.key_out    (key_out    )
);control u_control(.clk                    (clk                ),.rst_n                  (rst_n              ),.key                    (key_out            ),.time_data              (time_data          ),.alarm_clk_flag         (alarm_clk_flag     ),.shan_shuo              (shan_shuo            )
);beep u_beep(.clk                (clk                ),.rst_n              (rst_n              ),.alarm_clk_flag     (alarm_clk_flag     ),.beep               (beep               )
);endmodule

总结:实际上就是把前面学的按键消抖、蜂鸣器、时钟、状态机,组合起来用,真正需要写的就只有控制模块,其他模块基本改改原来的代码就能用了。
只要把状态机的情况考虑完了,先把状态机前两段写完,后面就是慢慢添小逻辑就可以了,唯一烦恼的就是有时候第三段需要写的东西太多,一时间有点晕,没有一条完整的思路链直接写完,我就是想到哪写哪,最后磕磕绊绊把这个程序调试出来了,不过是直接上板,哪个功能不对改哪里的代码,因为我感觉,像这种信号多的一批的程序,要是去写仿真文件都得想晕(实际上就是自己的调试能力不够,哈哈)。

状态机实现数字时钟 fpga相关推荐

  1. OLED数字时钟---FPGA实现

    一. 硬件 FPGA开发版 4个按键 0.96寸 IIC接口的oled显示模块 二. 功能介绍 oled初始化 oled清屏 oled数字时钟显示 oled字符显示 三. 效果演示 关注 微信公众号 ...

  2. FPGA学习之 状态机实现数码管的数字时钟

    FPGA学习之 状态机实现数字时钟 开发板型号:EP4CE6F17C8 六位数码管原理图: 由图可知,数码管段选和片选均为低电平有效. 由于人眼的视觉残留,我们控制一定频率对每一位数码管进行刷新,就能 ...

  3. 基于FPGA的遥控数字时钟设计

    基于FPGA的遥控数字时钟设计报告 ​ ​ Author:张宏宇 摘要 ​ 数字时钟是一种通过数字显示时间的计时装置,本次项目采用Cyclone Ⅳ系列芯片,使用QuartusII开发环境,使用Ver ...

  4. FPGA期末项目 | 数字时钟

    戳这里下载整个项目包(已上传到CSDN资源库) 一.实验设备 FPGA开发平台.计算机.其它外接器件 二.需求分析(选题的意义.功能要求等...这里有点水,小伙伴们可以选择性跳过) 选题的意义:个人认 ...

  5. 基于FPGA的数字时钟的设计课设(HUAT)

    目录 前言 一.数字时钟课设目标 二.部分代码 1.clock.v代码的编写 2.完整代码 3.仿真代码 总结 前言 学校黄老师的FPGA的设计课设,最后的课设为数字时钟,实现分时的计数功能,带有整点 ...

  6. 基于FPGA的数字时钟设计

    基于FPGA的数字时钟设计 芯片与开发板 技术指标 1.具有正常的日时分秒技术显示功能,用七个数码管分别显示日,时,分,秒. 2.有按键校日,校时,校分,校秒. 3.利用led模拟整点报时功能. 4. ...

  7. 基于FPGA数字时钟的设计(附源码)

    大侠好,欢迎来到FPGA技术江湖,江湖偌大,相见即是缘分.大侠可以关注"FPGA技术江湖"微信公众号,在"闯荡江湖"."行侠仗义"栏里获取其 ...

  8. FPGA芯片结构(可编程输入输出单元IOB/可配置逻辑块CLB/数字时钟管理模块DCM/ 嵌入式块RAM(BRAM)/丰富的布线资源/ 底层内嵌功能单元/内嵌专用硬核)

    目前主流的FPGA仍是基于查找表技术的,已经远远超出了先前版本的基本性能,并且整合了常用功能(如RAM.时钟管理 和DSP)的硬核(ASIC型)模块.如图1-1所示(注:图1-1只是一个示意图,实际上 ...

  9. FPGA数字时钟(可暂停调数,含代码)

    前言 前段时间刚刚开始初步学习FPGA相关知识,在学习了一段时间后,利用前面所学知识,写了一个数字时钟,顺便在这里写下总结,方便理解. (本人小白一名,有错欢迎指出,欢迎探讨) (我使用的开发板是Cy ...

最新文章

  1. 设计模式——装饰者模式
  2. mysql无级分销_3级分销(mysql存储过程写法)
  3. ArcGIS API for JavaScript 4.4学习笔记[新] AJS4.4和AJS3.21新特性
  4. 如何基于多线程队列简单实现mq
  5. Netty实现自定义协议
  6. linux下安装php的swoole扩展模块(安装后php加载不出来?)
  7. python安装opencv出现错误,通过pip安装opencv时出错
  8. 七牛云存储:通过SDK上传图片
  9. MySQL数据库权限管理
  10. Dubbo 需求、架构、使用Demo
  11. ruby array_Ruby中带有示例的Array.fill()方法(1)
  12. 115_Power Pivot之HR薪酬计算:公积金、社保、个税、实发工资相关
  13. Windows进程通信之共享内存通信(C++)
  14. python 字符串_Python中常用的8种字符串操作方法
  15. ORACLE 锁解释
  16. 徐姗姗 20190912-2 命令行
  17. 阿里云游戏服务器攻击怎么防御?
  18. mysql 相同分数排名
  19. 中国象棋对局软件设计(四)[完]
  20. heavy r.com index.php,AngularJS - Computation-Heavy Tasks

热门文章

  1. 初级前端如何突破瓶颈(瓶颈期怎么办)
  2. (4)第一个单机项目手机锁----------Service的实现
  3. H5 div标签详解
  4. 26个字母vs几万个汉字,中国人的打字机曾造得多艰难?
  5. excel中取消合并单元格后内容自动填充(合并的行拆成多行)
  6. LEETCODE | PYTHON | 1207 | 独一无二的出现次数
  7. Java怎么做置顶_[Java教程]自定义置顶TOP按钮
  8. 如何使用echart的Graph图实现一个流程控制图
  9. java空教室设计报告_空闲教室查询
  10. 基于QT实现简单的连连看小游戏