总体概述
硬件总体框图
软件设计
3.1 软件总体框图
高电平信号
3.2 数码管位选设计
仿真结果
4.1 分频仿真结果
出现的问题及解决办法
6.附录:
module shizhongover(clk,rst,seg,dig,key);
/*输入输出定义*/
input clk,rst;
input key;
output [7:0]seg;
output [7:0]dig;
/*定义寄存器型变量*/
wire[7:0] seg;
wire[7:0] dig;
reg[25:0] counter;
reg[5:0] sec;
reg[5:0] min;
reg[5:0] hour;
reg[7:0] seg_r;          //定义数码管输出寄存器
reg[7:0] dig_r;          //定义数码管选择输出寄存器
reg[3:0] disp_dat;       //定义显示数据寄存器
reg[2:0]count;           //定义计数寄存器
reg[3:0] a,b,c,d,e,f;
reg key_o; //按键输出
reg [3:0]key_d;          //按键输入
reg [1:0]button=2'b0;
reg [31:0]cnt = 32'd0;
reg [31:0]cnt1 = 32'd0;
reg  clk_5kHz;
assign dig = dig_r;      //输出数码管选择
assign seg = seg_r;
reg clk_1kHz;
always @(posedge clk)
if(cnt1 >=25000) 
begin   
cnt1 <= 1'b0;  
clk_1kHz = ~clk_1kHz; 
end  
else cnt1 <= cnt1 + 1'b1;  
always @(posedge clk_1kHz)
//定义上升沿触发进程
begin
count <= count + 1'b1;
end
/*时钟显示*/
always @(posedge clk_1kHz)
begin
a=hour/10;
b=hour%10;
c=min/10;
d=min%10;
e=sec/10;
f=sec%10;
case(count)                     //选择扫描显示数据
3'd0:disp_dat = a;              //第一个数码管
3'd1:disp_dat = b;              //第二个数码管
3'd2:disp_dat = 4'ha;           //第三个数码管
3'd3:disp_dat = c;              //第四个数码管
3'd4:disp_dat = d;              //第五个数码管
3'd5:disp_dat = 4'ha;           //第六个数码管
3'd6:disp_dat = e;              //第七个数码管
3'd7:disp_dat = f;              //第八个数码管
endcase
case(count)
//选择数码管显示位
3'd0:dig_r = 8'b01111111;       //选择第一个数码管显示
3'd1:dig_r = 8'b10111111;       //选择第二个数码管显示
3'd2:dig_r = 8'b11011111;
//选择第三个数码管显示
3'd3:dig_r = 8'b11101111;       //选择第四个数码管显示
3'd4:dig_r = 8'b11110111;       //选择第五个数码管显示
3'd5:dig_r = 8'b11111011;
//选择第六个数码管显示
3'd6:dig_r = 8'b11111101;       //选择第七个数码管显示
3'd7:dig_r = 8'b11111110;       //选择第八个数码管显示
endcase
end
always @(disp_dat)
begin
case(disp_dat)//七段译码
4'h0:seg_r = 8'hc0;            //显示 0
4'h1:seg_r = 8'hf9;            //显示 1
4'h2:seg_r = 8'ha4;            //显示 2
4'h3:seg_r = 8'hb0;            //显示 3
4'h4:seg_r = 8'h99;            //显示 4
4'h5:seg_r = 8'h92;            //显示 5
4'h6:seg_r = 8'h82;            //显示 6
4'h7:seg_r = 8'hf8;            //显示 7
4'h8:seg_r = 8'h80;            //显示 8
4'h9:seg_r = 8'h90;            //显示 9
4'ha:seg_r = 8'b10111111;      //显示—
endcase
end
/*按键分频程序*/
always @(posedge clk)
if(cnt >=5000) 
begin   
cnt <= 1'b0;  
clk_5kHz = ~clk_5kHz; 
end  
else cnt <= cnt + 1'b1;
/*按键信号取样程序*/
always @(posedge clk_5kHz)
begin
key_d[3:1]<=key_d[2:0];
key_d[0]<=key;
if  (key_d==4'b1111)          
     key_o <= 1'b0;
else if (key_d==4'b0000)  
     key_o <= 1'b1;
end  
always @(posedge key_o)
begin
button<=button+1;
if(button==2'b10) button<=0;
end
/*计数器设计和复位信号检测和响应*/
always@(posedge clk or negedge rst)
begin
/*复位信号有效*/
if(!rst)
begin
counter<=0;
end
else
begin
counter<=counter+1;
/*选择计时速度*/
if(button==2'b00)
begin
if(counter==30'd50000000)   //以1s的速度加一
begin
counter<=0;
sec<=sec+1; //秒加一
end
end
else if(button==2'b01)
begin
if(counter==30'd5000000)    //以0.1s的速度加一
begin
counter<=0;
sec<=sec+1;//秒加一
end
end
else
begin
if(counter==30'd500000)     //以0.01s的速度加一
begin
counter<=0;
sec<=sec+1;//秒加一
end
end
if(sec>=59)
begin
sec<=0;
min<=min+1;
end
if(min>=59 && sec>=59)     //分钟换算
begin
min<=0;
hour<=hour+1;
end
if(hour>=23 && min>=59 && sec>=59) //小时换算
begin
hour<=0;
end
end
end
endmodule