fpga学习之数码管显⽰
1、设计需求:
设计⼀个数码管驱动电路,是数码管能够显⽰任意六位数。
2、数码管原理分析:
现在的数码管基本都是⼋段式的,也就是说由⼋个发光⼆极管组成的。如图⼀所⽰,这是单个数码管的原理图
我们需要⼆极管显⽰数字,只需要控制⼆极管的亮灭就⾏。以共阳极数码管为例(给⼆极管低电平为点亮⼆极管),如图⼆所⽰显⽰数字与段选关系
数码管位选如图三所⽰,Y0~Y7表⽰8位数码管。1为数码管有效
代码功能实现部分:
module g_6(
Clk,
Rst_n,
En,
disp_data,
l,
g
);
);
input Clk; //50M
input Rst_n;
input En; //数码管显⽰使能,1使能,0关闭
input [23:0]disp_data;
output [5:0] l;//数码管位选(选择当前要显⽰的数码管) output reg [6:0] g;//数码管段选(当前要显⽰的内容)
reg [14:0]divider_cnt;//25000-1
reg clk_1K;
reg [5:0]l_r;
reg [3:0]data_tmp;//数据缓存
// 分频计数器计数模块
always@(podge Clk or negedge Rst_n)
if(!Rst_n)
divider_cnt <= 15'd0;
el if(!En)
divider_cnt <= 15'd0;
el if(divider_cnt == 24999)
divider_cnt <= 15'd0;
el
divider_cnt <= divider_cnt + 1'b1;
//1K扫描时钟⽣成模块
always@(podge Clk or negedge Rst_n)
金菌灵胶囊
if(!Rst_n)
clk_1K <= 1'b0;
el if(divider_cnt == 24999)
自制猪肉脯
clk_1K <= ~clk_1K;
el
clk_1K <= clk_1K;
//6位循环移位寄存器,实现数码管的位选
always@(podge clk_1K or negedge Rst_n)
if(!Rst_n)
l_r <= 6'b00_0001;
el if(l_r == 6'b10_0000)
l_r <= 6'b00_0001;
輮怎么读el
l_r <= l_r << 1;
always@(*)
ca(l_r)
6'b00_0001:data_tmp = disp_data[3:0];
6'b00_0010:data_tmp = disp_data[7:4];
6'b00_0100:data_tmp = disp_data[11:8];
6'b00_1000:data_tmp = disp_data[15:12];
6'b01_0000:data_tmp = disp_data[19:16];
6'b10_0000:data_tmp = disp_data[23:20];
default:data_tmp = 4'b0000;
endca
always@(*)
ca(data_tmp)
4'h0:g = 7'b1000000;
4'h1:g = 7'b1111001;
4'h2:g = 7'b0100100;
白腹隼雕4'h3:g = 7'b0110000;
4'h4:g = 7'b0011001;
4'h5:g = 7'b0010010;
4'h5:g = 7'b0010010;
4'h6:g = 7'b0000010;
4'h7:g = 7'b1111000;
4'h8:g = 7'b0000000;
4'h9:g = 7'b0010000;
4'ha:g = 7'b0001000;
4'hb:g = 7'b0000011;
4'hc:g = 7'b1000110;
4'hd:g = 7'b0100001;
4'he:g = 7'b0000110;
4'hf:g = 7'b0001110;
endca
assign l = (En)?l_r:6'b00_0000;
endmodule
代码仿真部分
`timescale 1ns/1ns
`define clk_period 20
module g_6_tb;
reg Clk; //50M
reg Rst_n;
藏族美食reg En; //数码管显⽰使能,1使能,0关闭
reg [23:0]disp_data;
wire [5:0] l;//数码管位选(选择当前要显⽰的数码管) wire [6:0] g;//数码管段选(当前要显⽰的内容)
g_6 g_6(
.Clk(Clk),
.Rst_n(Rst_n),
.En(En),
.disp_data(disp_data),
.l(l),
.g(g)
);
initial Clk = 1;
always#(`clk_period/2) Clk = ~Clk;
initial begin
乌鸡汤放什么补气补血Rst_n = 1'b0;
En = 1;
disp_data = 24'h123456;
#(`clk_period*20);
Rst_n = 1;
驾校改革#(`clk_period*20);
#10000000;
disp_data = 24'h876543;
违禁电器检讨书#10000000;
disp_data = 24'h89abcd;
#10000000;
$stop;
end
endmodule
仿真波形
⼤家在位选部分也可以使⽤状态机来实现,欢迎⼤家来学习讨论。