数码管的内部图:
(1)实验任务
使用FPGA开发板上的6位数码管以静态方式依次显示000000、111111、222222至FFFFFF,结束后继续从000000开始计数,每0.5s变化一次。
(2)硬件设计
使用的是6位共阳数码管。增加FPGA输出信号的驱动能力,使用
(3)程序设计
根据实验任务,我们可以大致规划出系统的控制流程:首先我们需要一个静态数码管显示模块在数码管上显示数据,其次需要一个计时模块每当计时到0.5s时改变数码管显示的数值。由此画出系统的功能框图如下所示:
顶层模块中例化两个模块,计时模块和数码管显示模块,实现模块之间的交互,计时模块将计时到0.5s时的标志信号flag传递给数码管静态显示模块,数码管静态显示模块接收到此信号时显示的数值增加1。
计时模块(time_count):计时模块对系统时钟进行计数,当计时到给定值(此处指0.5s)时输出标志信号。
数码管静态显示模块(seg_led_static):数码管静态显示模块在数码管上以静态方式显示数值。
module timer(
input sys_clk,
input sys_rst_n,
output reg flag
);
parameter MAX_NUM = 25000_000;
reg [24:0] count;
always @(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)begin
flag <= 1'b0;
count <= 24'b0;
end
else if(count < MAX_NUM - 1'b0)begin
flag <= 1'b0;
count <= count + 1'b1;
end
else begin
flag <= 1'b1;
count <= 24'b0;
end
end
endmodule
module seg_led_static(
input sys_clk,
input sys_rst_n,
input add_flag,
output reg [5:0] sel,
output reg [7:0] seg_led
);
reg [3:0] num;
//控制数码管位选信号(低电平有效),选中所有的数码管
always @(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)
sel <= 6'b111111;
else
sel <= 6'b000000;
end
//每次通知信号到达时,数码管显示的十六进制数值加1
always @(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)
num <= 4'h0;
else if(add_flag)begin
if(num < 4'hf)
num <= num + 1'b1;
else
num <= 4'h0;
end
else
num <= num;
end
//根据数码管显示的数值,控制段选信号
always @ (posedge sys_clk or negedge sys_rst_n) begin
if (!sys_rst_n)
seg_led <= 8'b0;
else begin
case (num)
4'h0 : seg_led <= 8'b1100_0000;
4'h1 : seg_led <= 8'b1111_1001;
4'h2 : seg_led <= 8'b1010_0100;
4'h3 : seg_led <= 8'b1011_0000;
4'h4 : seg_led <= 8'b1001_1001;
4'h5 : seg_led <= 8'b1001_0010;
4'h6 : seg_led <= 8'b1000_0010;
4'h7 : seg_led <= 8'b1111_1000;
4'h8 : seg_led <= 8'b1000_0000;
4'h9 : seg_led <= 8'b1001_0000;
4'ha : seg_led <= 8'b1000_1000;
4'hb : seg_led <= 8'b1000_0011;
4'hc : seg_led <= 8'b1100_0110;
4'hd : seg_led <= 8'b1010_0001;
4'he : seg_led <= 8'b1000_0110;
4'hf : seg_led <= 8'b1000_1110;
default : seg_led <= 8'b1100_0000;
endcase
end
end
endmodule
顶层模块
module segdisplay (
input sys_clk , // 系统时钟
input sys_rst_n, // 系统复位信号(低有效)
output [5:0] sel , // 数码管位选
output [7:0] seg_led // 数码管段选
);
//parameter define
parameter TIME_SHOW = 25'd25000_000; // 数码管变化的时间间隔0.5s
//wire define
wire add_flag; // 数码管变化的通知信号
//*****************************************************
//** main code
//*****************************************************
//每隔0.5s产生一个时钟周期的脉冲信号
//每隔0.5秒改变数码管显示的数值时此参数值为0.5 × 50000000 =
25000000
timer #(
.MAX_NUM (TIME_SHOW)
) u_timer(
.sys_clk (sys_clk ),
.sys_rst_n (sys_rst_n),
.flag (add_flag )
);
//每当脉冲信号到达时,使数码管显示的数值加1
seg_led_static u_seg_led_static (
.sys_clk (sys_clk ),
.sys_rst_n (sys_rst_n),
.add_flag (add_flag ),
.sel (sel ),
.seg_led (seg_led )
);
endmodule
(4)下载验证