文章目录
- verilog实现数码管静态显示
- 一、任务要求
- 二、实验代码
- 三、仿真代码
- 四、仿真结果
- 五、总结
verilog实现数码管静态显示
一、任务要求
六个数码管同时间隔0.5s显示0-f。要求:使用一个顶层模块,调用计时器模块和数码管静态显示模块。
二、实验代码
module time_count(
input clk ,//50MHz时钟信号
input rst_n,//复位信号
output reg flag//一个时钟周期的脉冲信号
);
parameter MAX_NUM = 25'd25_000_000;//计数器最大计数值
reg [24:0] cnt ; //时钟分频计数器
//计数器对时钟计数,每0.5s,输出一个时钟周期脉冲信号
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin//按复位时
cnt <= 25'd0;//计数器清零
end
else if(cnt == MAX_NUM - 1'b1)begin//如果没到时间
cnt <= 0;//计数器正常累计+1
end
else begin //否则到时间
cnt <= cnt + 1'b1;
end
end
always @(posedge clk or negedge rst_n) begin
if(~rst_n) begin
flag <= 1'b0;//信号为0
end
else if(cnt == MAX_NUM - 1'b1)begin
flag <= 1'b1;//信号为0
end
else begin
flag <= 1'b0;//信号变为1
end
end
endmodule
module seg_led_static(
input clk ,
input rst_n ,
input flag ,
output reg [5:0] sel ,//数码管位选信号
output reg [7:0] seg //数码管段选信号
);
parameter ZERO = 8'b1100_0000,
ONE = 8'b1111_1000,
TWO = 8'b1010_0100,
THREE = 8'b1011_0000,
FOUR = 8'b1001_1001,
FIVE = 8'b1001_0010,
SIX = 8'b1000_0010,
SEVEN = 8'b1111_1000,
EIGHT = 8'b1000_0000,
NINE = 8'b1001_0000,
A = 8'b1000_1000,
B = 8'b1000_0011,
C = 8'b1100_0110,
D = 8'b1010_0001,
E = 8'b1000_0110,
F = 8'b1000_1110;
reg [3:0] num;//数码管显示十六进制数
//控制数码管位选信号(注:低电平有效),选中所有的数码管
always @(posedge clk or negedge rst_n)begin
if(!rst_n)//如果按复位键0
sel <= 6'b111111;//则默认为高电平
else
sel <= 6'b000000;//否则为低电平
end
//每次通知信号flag到达时,数码管计数加1
always @(posedge clk or negedge rst_n)begin
if(!rst_n)
num <= 4'h0;
else if(flag)begin
if(num < 4'hf)
num <= num + 1'h1;
else
num <= 4'h0;
end
else begin
num <= num;
end
end
//根据数码管显示的数值,控制段选信号
always @(posedge clk or negedge rst_n)begin
if(!rst_n)
seg <= 8'b0;
else begin
case(num)//匹配16进制数
4'h0: seg <= 8'b1100_0000;//匹配到后参考共阳极真值表
4'h1: seg <= 8'b1111_1001;
4'h2: seg <= 8'b1010_0100;
4'h3: seg <= 8'b1011_0000;
4'h4: seg <= 8'b1001_1001;
4'h5: seg <= 8'b1001_0010;
4'h6: seg <= 8'b1000_0010;
4'h7: seg <= 8'b1111_1000;
4'h8: seg <= 8'b1000_0000;
4'h9: seg <= 8'b1001_0000;
4'ha: seg <= 8'b1000_1000;
4'hb: seg <= 8'b1000_0011;
4'hc: seg <= 8'b1100_0110;
4'hd: seg <= 8'b1010_0001;
4'he: seg <= 8'b1000_0110;
4'hf: seg <= 8'b1000_1110;
default : seg <= 8'b1100_0000;
endcase
end
end
endmodule
module top_seg_led_static(
input clk ,//50MHz系统时钟
input rst_n,//系统复位信号(低有效)
output [5:0] sel ,//数码管位选
output [7:0] seg//数码管段选
);
parameter MAX_NUM = 25'd25_000_000;// 数码管变化的时间间隔0.5s
wire add_flag ;// 数码管变化的通知信号
//每隔0.5s产生一个时钟周期的脉冲信号
time_count #(.MAX_NUM(MAX_NUM)) u_time_count(
.clk (clk) ,//50MHz时钟信号
.rst_n (rst_n),//复位信号
.flag (add_flag)//一个时钟周期的脉冲信号
);
//每当脉冲信号到达时,使数码管显示的数值加1
seg_led_static u_seg_led_static(
.clk (clk) ,
.rst_n (rst_n) ,
.flag (add_flag),
.sel (sel) ,
.seg (seg)
);
endmodule
三、仿真代码
`timescale 1ns/1ns
module top_seg_led_static_tb();
reg clk ;
reg rst_n ;
wire [5:0] sel ;
wire [7:0] seg ;
parameter CYCLE = 5'd20;//周期20ns
parameter MAX_NUM = 8'd100;//调小间隔时间100*20ns
always #(CYCLE/2) clk = ~clk;//翻转时钟
initial begin
clk = 0 ;//时钟初始为0
rst_n = 0 ;//复位初始为0
#(CYCLE) ;//延迟20ns
rst_n = 1 ;//复位置1
#(16*MAX_NUM*CYCLE);//显示0-f时间
$stop ;//停止
end
top_seg_led_static#(.MAX_NUM (MAX_NUM)) u_top_seg_led_static(
.clk (clk) ,//50MHz系统时钟
.rst_n (rst_n),//系统复位信号(低有效)
.sel (sel) ,//数码管位选
.seg (seg) //数码管段选
);
endmodule
四、仿真结果
五、总结
本文介绍了数码管显示原理,数码管驱动方式等等,并通过代码实现了数码管静态显示