提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
提示:这里可以添加本文要记录的大概内容:
前面学习了基本的数字芯片逻辑编程,学会了计数器等,这次来一个做一个综合应用。数字时钟,采用数码管显示时分秒。
提示:以下是本篇文章正文内容,下面案例可供参考
数字时钟是一种以数字显示取代模拟表盘的钟表,它能够以数字的形式显示当前的时间,并且可以同时显示时、分、秒。此外,它通常具有对时、分、秒进行准确校准的功能。
示例:能用数码管显示 时分秒的时钟
目标:动态数码管显示: 12345678
时间显示的状态效:”12.20.30 12-20.30 12-20-30
代码如下(示例):
代码如下(示例):
module seg(clk,seg7,ledcom);
input clk; // 假设系统提供的时钟 50Mhz
output[7:0] seg7; //段
output[7:0] ledcom; //位选
reg[7:0] seg7; //alway 里面赋值要用reg数据
reg[20:0] cnt;
reg[7:0] ledcom;
always@(posedge clk)
begin
if(cnt==21'b1 1111 1111 1111 1111 1111) // 2的22减一
cnt<=0;
else
cnt<=cnt+1;
end
always@(cnt) //给位选
begin
case(cnt[16:14]) // 14 15 16 000 ->111 前面13为 满进位
3'b000:ledcom<=8'b00000001;//0 只有一个位选为1 只有第一位数码管选中并显示
3'b001:ledcom<=8'b00000010;//1
3'b010:ledcom<=8'b00000100;//2
3'b011:ledcom<=8'b00001000;//3
3'b100:ledcom<=8'b00010000;//0
3'b101:ledcom<=8'b00100000;//1
3'b110:ledcom<=8'b01000000;//2
3'b111:ledcom<=8'b10000000;//3
endcase
end
always@(cnt) //段码
begin
case(cnt[16:14])
3'b000:seg7<=8'b00000111;//0 同时给到段码 ,保证只有 第一个数码管亮
3'b001:seg7<=8'b11011011;//1
3'b010:seg7<=8'b11001111;//2
3'b011:seg7<=8'b10100111;//3
3'b100:seg7<=8'b11101101;//0
3'b101:seg7<=8'b11111101;//1
3'b110:seg7<=8'b01000111;//2
3'b111:seg7<=8'b11111111;//3
endcase
end
endmodule
为了仿真改小了参数
module seg(clk,seg7,ledcom,cnt,en);
input en;
input clk; // 假设系统提供的时钟 50Mhz
output[7:0] seg7; //段
output[7:0] ledcom; //位选
reg[7:0] seg7; //alway 里面赋值要用reg数据
output reg[8:0] cnt;
reg[7:0] ledcom;
always@(posedge clk)
begin
if(!en)
cnt<=0;
else
if(cnt==8'b111111111) // 2的22减一
cnt<=0;
else
cnt<=cnt+1;
end
always@(cnt) //给位选
begin
case(cnt[7:5]) // 14 15 16 000 ->111 前面13为 满进位
3'b000:ledcom<=8'b00000001;//0 只有一个位选为1 只有第一位数码管选中并显示
3'b001:ledcom<=8'b00000010;//1
3'b010:ledcom<=8'b00000100;//2
3'b011:ledcom<=8'b00001000;//3
3'b100:ledcom<=8'b00010000;//0
3'b101:ledcom<=8'b00100000;//1
3'b110:ledcom<=8'b01000000;//2
3'b111:ledcom<=8'b10000000;//3
default:ledcom<=8'b10000000;
endcase
end
always@(cnt) //段码
begin
case(cnt[7:5])
3'b000:seg7<=8'b00000111;//0 同时给到段码 ,保证只有 第一个数码管亮
3'b001:seg7<=8'b11011011;//1
3'b010:seg7<=8'b11001111;//2
3'b011:seg7<=8'b10100111;//3
3'b100:seg7<=8'b11101101;//0
3'b101:seg7<=8'b11111101;//1
3'b110:seg7<=8'b01000111;//2
3'b111:seg7<=8'b11111111;//3
default:seg7<=8'b11111111;
endcase
end
endmodule
测试文件
`timescale 1 ps/ 1 ps
module seg_tb3();
// constants
// general purpose registers
reg eachvec;
// test vector input registers
reg clk;
reg en;
// wires
wire [8:0] cnt;
wire [7:0] ledcom;
wire [7:0] seg7;
// assign statements (if any)
seg i1 (
// port map - connection between master ports and signals/registers
.clk(clk),
.cnt(cnt),
.en(en),
.ledcom(ledcom),
.seg7(seg7)
);
initial
begin
// code that executes only once
// insert code here --> begin
// --> end
#10 clk= 0;
#100 en=0;
#10 en=1;
$display("Running testbench");
end
always #10 clk=~clk;
always
// optional sensitivity list
// @(event1 or event2 or .... eventn)
begin
// code executes for every event on sensitivity list
// insert code here --> begin
@eachvec;
// --> end
end
endmodule
实际仿真测试元件图
module watch(clk,reset,seg_r,dig_r);
input clk;
input reset;
output[7:0] seg_r;
output[7:0] dig_r;
reg[25:0] count;
reg[15:0] hour;
reg sec;
reg[4:0] disp_dat;
reg[7:0] seg_r;
reg[7:0] dig_r;
always @(posedge clk)
begin
count = count + 1'b1;
if(count == 26'd25000000)
begin
count = 26'd0;
sec = ~sec;
end
end
always @(posedge sec)
begin
if(reset==0)
hour[15:0]=0;
else
begin
hour[3:0] = hour[3:0]+1'b1;
if(hour[3:0] == 4'ha)
begin
hour[3:0] = 4'h0;
hour[7:4] = hour[7:4]+1'b1;
if(hour[7:4] == 4'h6)
begin
hour[7:4] = 4'h0;
hour[11:8] = hour[11:8] + 1'b1;
if(hour[11:8] ==4'ha)
begin
hour[11:8] = 4'h0;
hour[15:12] = hour[15:12] + 1'b1;
if(hour[15:12] == 4'h6)
hour[15:12] =4'h0;
end
end
end
end
end
always @(posedge clk)
begin
case(count[17:15])
3'd0:disp_dat = hour[3:0];
3'd1:disp_dat = hour[7:4];
3'd3:disp_dat = hour[11:8];
3'd4:disp_dat = hour[15:12];
endcase
case(count[17:15])
3'd0:dig_r = 8'b10000000;
3'd1:dig_r = 8'b01000000;
3'd2:dig_r = 8'b00000000;
3'd3:dig_r = 8'b00010000;
3'd4:dig_r = 8'b00001000;
3'd5:dig_r = 8'b00000000;
3'd6:dig_r = 8'b00000000;
3'd7:dig_r = 8'b00000000;
endcase
end
always @(posedge clk)
begin
case(disp_dat)
0:seg_r=8'b01111111;
1:seg_r=8'b00000111;
2:seg_r=8'b11011011;
3:seg_r=8'b11001111;
4:seg_r=8'b10100111;
5:seg_r=8'b11101101;
6:seg_r=8'b11111101;
7:seg_r=8'b01000111;
8:seg_r=8'b11111111;
9:seg_r=8'b11101111;
default:seg_r = 8'hff;
endcase
end
endmodule
提示:这里对文章进行总结: