一、总体方案
给出一个基本内容的实现方案,大家具体分析一下。留下不完善的地方待大家发现修改。
该方案选择动态扫描方式,扫描频率100hz,由系统提供的10MHz分频得到。同时系统时钟分频得到计数器需要的1hz的时钟。秒、分钟使用十进制的60进制和小时的24进制。显示部分有6个LED数码管,由于采用动态扫描方式显示,每一个时刻只有一组数据送到一个LED上显示,其他的数码管时不显示的,只要扫描频率大于人眼余晖时间(24HZ以上),我们看到的就是六个稳定显示的数据。Seltime模块实现六组数据的分时输出。Deled实现七段码译码功能,74138实现六个数码管的分时显示控制(留给大家任务,改成Verilog代码实现相同的功能)。
其他功能,如整点报警,调节时间等,自己扩展。
仿真过程大家自行进行。
二、部分参考程序如下:
秒模块参考程序:
module SECOND(
input clk, clr,
output [7:0] second,
output reg co
);
reg [7:0] cnt;
always @(posedge clk)
begin
if (clr)
begin
cnt<= 8'b00000000;
co <= 1;
end
else if (cnt[7:4] == 4'b0101 && cnt[3:0] == 4'b1001) //计数达到59时,输出清零
begin
co <= 0;
cnt<= 8'b00000000;
end
else if(cnt[3:0] == 4'b1001) //低位达到9时,低位清零,高位加1
begin
cnt[3:0] <= 4'b0000;
cnt[7:4] <= cnt[7:4] + 1'b1;
end
else
begin
cnt[3:0] <= cnt[3:0] + 1'b1;
co <= 1;
end
end
assign second = cnt;
endmodule
小时模块参考程序:
//8421BCD码计数器,模24
module hour(clk,rst,dout);
input clk, rst;
output[7:0] dout;
reg[7:0] dout;
always@(posedge clk)
begin
if(rst) //复位信号有效时,置位
dout <= 8'b00000000;
else if( (dout[7:4] == 4'b0010)&&(dout[3:0] == 4'b0011) ) //计数达到23时,输出清零
dout <= 8'b00000000;
else if(dout[3:0] == 4'b1001) //低位达到9时,低位清零,高位加1
begin
dout[3:0] <= 4'b0000;
dout[7:4] <= dout[7:4] + 1'b1;
end
else
dout[3:0] <= dout[3:0] + 1'b1;
end
endmodule
分频模块:
module dfre(clk10MHz,clk1hz);
input clk10MHz;
output reg clk1hz;
reg[23:0] q;
always@(posedge clk10MHz)
begin
if (q==5000000)
begin
q<=0;
clk1hz=~clk1hz;
end
else q<=q+1;
end
endmodule
动态扫描数据分时输出模块:
// 动态扫描控制电路
module seltime(
input ckdsp,
input reset,
input [7:0] second,
input [7:0] minute,
input [7:0] hour,
output reg [3:0] daout,
output [2:0] sel
);
reg [2:0] sec;
always @(posedge ckdsp)
begin
if (reset == 1'b0)
sec <= 3'b000;
else if (sec == 3'b101)
sec <= 3'b000;
else
sec <= sec + 1;
end
always @(sec or second or minute or hour)
begin
case (sec)
3'b000: daout <= second[3:0];
3'b001: daout <= second[7:4];
3'b010: daout <= minute[3:0];
3'b011: daout <= minute[7:4];
3'b100: daout <= hour[3:0];
3'b101: daout <= hour[7:4];
default: daout <= 4'bXXXX;
endcase
end
assign sel = sec;
endmodule
七段码译码器模块:
//七段码译码器
module DELED(
input [3:0] S,
output A, B, C, D, E, F, G, H
);
reg [3:0] DATA;
reg [7:0] DOUT;
always @(S) begin
case (S)
///以下是驱动共阳极数码管 hgfedcba
4'b0000: DOUT <= 8'b11000000; //显示0
4'b0000: DOUT <= 8'b11111001; //显示1
4'b0000: DOUT <= 8'b10100100; //显示2
4'b0000: DOUT <= 8'b10110000; //显示3
4'b0000: DOUT <= 8'b10011001; //显示4
4'b0000: DOUT <= 8'b10010010; //显示5
4'b0000: DOUT <= 8'b10000010; //显示6
4'b0000: DOUT <= 8'b11111000; //显示7
4'b0000: DOUT <= 8'b10000000; //显示8
4'b0000: DOUT <= 8'b10010000; //显示9
4'b0000: DOUT <= 8'b10001000; //显示a
4'b0000: DOUT <= 8'b10000011; //显示b
4'b0000: DOUT <= 8'b11000110; //显示c
4'b0000: DOUT <= 8'b10100001; //显示d
4'b0000: DOUT <= 8'b10000110; //显示e
4'b0000: DOUT <= 8'b10001110; //显示f
default: DOUT <= 8'b11111111;
///以下是驱动共阴极数码管
/// 4'b0000: DOUT <= 8'b00111111;
/// 4'b0001: DOUT <= 8'b00000110;
/// 4'b0010: DOUT <= 8'b01011011;
/// 4'b0011: DOUT <= 8'b01001111;
/// 4'b0100: DOUT <= 8'b01100110;
/// 4'b0101: DOUT <= 8'b01101101;
/// 4'b0110: DOUT <= 8'b01111101;
/// 4'b0111: DOUT <= 8'b00000111;
/// 4'b1000: DOUT <= 8'b01111111;
/// 4'b1001: DOUT <= 8'b01101111;
/// 4'b1010: DOUT <= 8'b01110111;
/// 4'b1011: DOUT <= 8'b01111100;
/// 4'b1100: DOUT <= 8'b00111001;
/// 4'b1101: DOUT <= 8'b01011110;
/// 4'b1110: DOUT <= 8'b01111001;
/// 4'b1111: DOUT <= 8'b01110001;
/// default: DOUT <= 8'b00000000;
endcase
end
assign H = DOUT[7];
assign G = DOUT[6];
assign F = DOUT[5];
assign E = DOUT[4];
assign D = DOUT[3];
assign C = DOUT[2];
assign B = DOUT[1];
assign A = DOUT[0];
endmodule