实现功能:1位数码管实现0~9计数。
实验现象:
第1秒: 1位数码管显示0,
第2秒: 1位数码管显示1,
第3秒: 1位数码管显示2,
第4秒: 1位数码管显示3,
第5秒: 1位数码管显示4,
第6秒: 1位数码管显示5,
第7秒: 1位数码管显示6,
第8秒: 1位数码管显示7,
第9秒: 1位数码管显示8,
第10秒: 1位数码管显示9,
……
10s一个周期,重复进入下一次循环。
代码实现:
//秒表模块,0~9计数
module stopwatch(
input clk,
input rst_n,
output reg [5:0] seg_sel,//位选
output reg [7:0] seg_ment//段选
);
// 计数器cnt_1s循环计数,计到cnt_1s_max-1得到1s
parameter cnt_1s_max = 26'd5000_0000;
reg [25:0] cnt_1s;
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
cnt_1s <= 25'd0;
else if(cnt_1s == cnt_1s_max)
cnt_1s <= 25'd0;
else
cnt_1s <= cnt_1s + 1'b1;
end
// 计数器cnt_10,计到9为10次
parameter cnt_10_max = 4'd10 - 1'b1;
reg [3:0] cnt_10;
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
cnt_10 <= 4'd0;
else if(cnt_10 == cnt_10_max && cnt_1s == cnt_1s_max)
cnt_10 <= 4'd0;
else if(cnt_1s == cnt_1s_max)
cnt_10 <= cnt_10 + 1'b1;
else
cnt_10 <= cnt_10;
end
//位选信号
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
seg_sel <= 6'b111111;
else
seg_sel <= 6'b111110;//位选信号,低电平有效
end
//段选信号
always@(posedge clk or negedge rst_n) begin
if (!rst_n)
seg_ment <= 8'b1100_0000;
else begin
case(cnt_10)
4'd0: seg_ment <= 8'b1100_0000;
4'd1: seg_ment <= 8'b1111_1001;
4'd2: seg_ment <= 8'b1010_0100;
4'd3: seg_ment <= 8'b1011_0000;
4'd4: seg_ment <= 8'b1001_1001;
4'd5: seg_ment <= 8'b1001_0010;
4'd6: seg_ment <= 8'b1000_0010;
4'd7: seg_ment <= 8'b1111_1000;
4'd8: seg_ment <= 8'b1000_0000;
4'd9: seg_ment <= 8'b1001_0000;
default: seg_ment <= 8'b1100_0000;
endcase
end
end
endmodule
实现功能:1位数码管实现0~9计数。
实验现象:
第1秒: 1位数码管显示0,
第2~3秒: 1位数码管显示1,
第4~6秒: 1位数码管显示2,
第7~10秒: 1位数码管显示3,
第11~15秒: 1位数码管显示4,
第16~21秒: 1位数码管显示5,
第22~28秒: 1位数码管显示6,
第29~36秒: 1位数码管显示7,
第37~45秒: 1位数码管显示8,
第46~55秒: 1位数码管显示9,
……
55s一个周期,重复进入下一次循环。
代码实现:
//秒表模块,0~9计数
//1s--0,2s--1,……,10s--9
module stopwatch_10s(
input clk,
input rst_n,
output reg [5:0] seg_sel,//位选
output reg [7:0] seg_ment//段选
);
// 计数器cnt_1s循环计数,计到cnt_1s_max-1得到1s
parameter cnt_1s_max = 26'd5000_0000;
reg [25:0] cnt_1s;
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
cnt_1s <= 25'd0;
else if(cnt_1s == cnt_1s_max)
cnt_1s <= 25'd0;
else
cnt_1s <= cnt_1s + 1'b1;
end
// 计数器cnt_s循环计数,计到cnt_s_max-1
reg [3:0] cnt_s_max;
reg [3:0] cnt_s;
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
cnt_s <= 4'd0;
else if(cnt_s == cnt_s_max && cnt_1s == cnt_1s_max)
cnt_s <= 4'd0;
else if(cnt_1s == cnt_1s_max)
cnt_s <= cnt_s + 1'b1;
else
cnt_s <= cnt_s;
end
// 计数器cnt_10,计到9为10次
parameter cnt_10_max = 4'd10 - 1'b1;
reg [3:0] cnt_10;
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
cnt_10 <= 4'd0;
else if(cnt_10 == cnt_10_max && cnt_s == cnt_s_max && cnt_1s == cnt_1s_max)
cnt_10 <= 4'd0;
else if(cnt_s == cnt_s_max && cnt_1s == cnt_1s_max)
cnt_10 <= cnt_10 + 1'b1;
else
cnt_10 <= cnt_10;
end
//每次数码管显示数字的时长
always@(*) begin
case(cnt_10)
4'd0: cnt_s_max <= 4'd1;
4'd1: cnt_s_max <= 4'd2;
4'd2: cnt_s_max <= 4'd3;
4'd3: cnt_s_max <= 4'd4;
4'd4: cnt_s_max <= 4'd5;
4'd5: cnt_s_max <= 4'd6;
4'd6: cnt_s_max <= 4'd7;
4'd7: cnt_s_max <= 4'd8;
4'd8: cnt_s_max <= 4'd9;
4'd9: cnt_s_max <= 4'd10;
default: cnt_s_max <= 4'd1;
endcase
end
//位选信号
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
seg_sel <= 6'b111111;
else
seg_sel <= 6'b111110;//位选信号,低电平有效
end
//段选信号
always@(posedge clk or negedge rst_n) begin
if (!rst_n)
seg_ment <= 8'b1100_0000;
else begin
case(cnt_10)
4'd0: seg_ment <= 8'b1100_0000;
4'd1: seg_ment <= 8'b1111_1001;
4'd2: seg_ment <= 8'b1010_0100;
4'd3: seg_ment <= 8'b1011_0000;
4'd4: seg_ment <= 8'b1001_1001;
4'd5: seg_ment <= 8'b1001_0010;
4'd6: seg_ment <= 8'b1000_0010;
4'd7: seg_ment <= 8'b1111_1000;
4'd8: seg_ment <= 8'b1000_0000;
4'd9: seg_ment <= 8'b1001_0000;
default: seg_ment <= 8'b1100_0000;
endcase
end
end
endmodule
实现功能:6位数码管同时显示相同的数字,1s改变一次,数字按照"02468ACE13579bdF"的顺序显示。
实验现象:
第1秒: 6位数码管显示0,
第2秒: 6位数码管显示2,
第3秒: 6位数码管显示4,
第4秒: 6位数码管显示6,
第5秒: 6位数码管显示8,
第6秒: 6位数码管显示A,
第7秒: 6位数码管显示C,
第8秒: 6位数码管显示E,
第9秒: 6位数码管显示1,
第10秒: 6位数码管显示3,
第11秒: 6位数码管显示5,
第12秒: 6位数码管显示7,
第13秒: 6位数码管显示9,
第14秒: 6位数码管显示b,
第15秒: 6位数码管显示d,
第16秒: 6位数码管显示F,
……
16s一个周期,重复进入下一次循环。
代码实现:
//数字显示模块:1s改变一次,按照02468ACE13579bdF顺序显示
module data_display(
input clk,
input rst_n,
output reg [5:0] seg_sel,//位选
output reg [7:0] seg_ment//段选
);
// 计数器cnt_1s循环计数,计到cnt_1s_max-1得到1s
parameter cnt_1s_max = 26'd5000_0000;
reg [25:0] cnt_1s;
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
cnt_1s <= 25'd0;
else if(cnt_1s == cnt_1s_max)
cnt_1s <= 25'd0;
else
cnt_1s <= cnt_1s + 1'b1;
end
// 计数器cnt_16,计到15为16次
parameter cnt_16_max = 4'd15;
reg [3:0] cnt_16;
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
cnt_16 <= 4'd0;
else if(cnt_16 == cnt_16_max && cnt_1s == cnt_1s_max)
cnt_16 <= 4'd0;
else if(cnt_1s == cnt_1s_max)
cnt_16 <= cnt_16 + 1'b1;
else
cnt_16 <= cnt_16;
end
//位选信号
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
seg_sel <= 6'b111111;
else
seg_sel <= 6'b000000;//位选信号,低电平有效
end
//段选信号
always@(posedge clk or negedge rst_n) begin
if (!rst_n)
seg_ment <= 8'b1100_0000;
else begin
case(cnt_16)
4'd0: seg_ment <= 8'b1100_0000;//0
4'd1: seg_ment <= 8'b1010_0100;//2
4'd2: seg_ment <= 8'b1001_1001;//4
4'd3: seg_ment <= 8'b1000_0010;//6
4'd4: seg_ment <= 8'b1000_0000;//8
4'd5: seg_ment <= 8'b1000_1000;//A(10)
4'd6: seg_ment <= 8'b1100_0110;//C(12)
4'd7: seg_ment <= 8'b1000_0110;//E(14)
4'd8: seg_ment <= 8'b1111_1001;//1
4'd9: seg_ment <= 8'b1011_0000;//3
4'd10: seg_ment <= 8'b1001_0010;//5
4'd11: seg_ment <= 8'b1111_1000;//7
4'd12: seg_ment <= 8'b1001_0000;//9
4'd13: seg_ment <= 8'b1000_0011;//B(11)
4'd14: seg_ment <= 8'b1010_0001;//D(13)
4'd15: seg_ment <= 8'b1000_1110;//F(15)
default: seg_ment <= 8'b1100_0000;//0
endcase
end
end
endmodule
注:本案例为静态数码管显示实验,由计时器和数码管显示构成,实现设定的3个功能,在正点原子FPGA开拓者开发板上亲测有效。