当前位置:网站首页>Verilog 实现数码管显视驱动【附源码】
Verilog 实现数码管显视驱动【附源码】
2022-07-07 09:02:00 【青柠Miya】
目录
1、实验平台
软件:PC、Quartus Prime 18.1、Modelsim 10.5b
硬件:Altera FPGA开发板(EP4CE6E22F17C8)
2、实验目的
- 1、掌握数码管的静态显示与动态刷新
- 2、计数器练习
2.1、实验内容
静态显示 0~F
动态显示-秒表设计
3、实验流程
3.1、实验原理
根据开发板的原理图,可得到以下资料
数码管:本质上为一组发光二极管按照一定顺序排列而成,其显示原理与LED无异。
根据硬件原理图所示,发光二极管,所有的阳极都接通3.3V的正电压,也即—高电平,所以如果我们想要
发光二极管导通的话,需要在阴极接通低电平,就可以让LED亮起来。
3.2、系统架构
根据系统要求,可以得到以下框架分布
3.3、功能模块划分
根据系统构建,可得到以下模块
3.3.1、数据产生模块
模块框图
信号定义
信号名 | 端口类型 | 数据位宽 | 信号说明 |
---|---|---|---|
Clk | i | 1 | 输入时钟信号,50MHz |
Rst_n | i | 1 | 输入复位信号,低电平有效 |
data_o | O | 32 | 输出待显示数据,8位数码管可显示32位16进制数据 |
设计文件
/*================================================*\ Filename ﹕data_gen.v Author ﹕Adolph Description ﹕产生数码管需要显示的数据. 32'h11111111~32'h33333333; Called by ﹕seg_top.v Revision History ﹕ 2022-6-6 15:49:24 Revision 1.0 Email﹕[email protected] Company﹕ \*================================================*/
module data_gen(
input clk ,
input rst_n,
output reg [31:0] data_dis
);
parameter TIME_DELAY = 25'd2500;
reg [24:0] cnt_delay;
[email protected](posedge clk or negedge rst_n)begin
if(!rst_n)begin
cnt_delay <= 25'd0;
end
else if(cnt_delay >= TIME_DELAY - 25'd1)begin
cnt_delay <= 25'd0;
end
else begin
cnt_delay <= cnt_delay + 25'd1;
end
end
[email protected](posedge clk or negedge rst_n)begin
if(!rst_n)begin
data_dis <= 32'h1111_1111;
end
else if(data_dis == 32'h3333_3333)begin
data_dis <= 32'h1111_1111;
end
else if(cnt_delay >= TIME_DELAY - 25'd1)begin
data_dis <= data_dis + 32'h1;
end
else begin
data_dis <= data_dis;
end
end
endmodule
本模块较为简单,此处不做仿真验证,如有兴趣可自行验证
3.3.2、数码管驱动模块
模块框图
信号定义
信号名 | 端口类型 | 数据位宽 | 信号说明 |
---|---|---|---|
Clk | i | 1 | 输入时钟信号,50MHz |
Rst_n | i | 1 | 输入复位信号,低电平有效 |
data_in | i | 32 | 输入按键消抖信号,高电平有效 |
dig_sel | O | 8 | 数码管位选信号,由原理图可知,低电平有效 |
dig_seg | O | 8 | 数码管段选信号,由原理图可知,低电平有效 |
设计文件
/*================================================*\ Filename ﹕seg_driver.v Author ﹕Adolph Description ﹕对输入的数据译码,并驱动数码管显示对应数据 Called by ﹕seg_top.v Revision History ﹕ 2022-5-30 14:27:22 Revision 1.0 Email﹕[email protected] Company﹕ \*================================================*/
module seg_driver(
input clk ,
input rst_n ,
input [31:0]dis_data,//待显示的数据
output reg[7:0] dig_sel ,
output reg[7:0] dig_seg
);
//wire [31:0]dis_data;
// assign dig_seg = 8'd0;
// assign dig_sel = 1'b0;
localparam
NUM_0 = 8'hC0,
NUM_1 = 8'hF9,
NUM_2 = 8'hA4,
NUM_3 = 8'hB0,
NUM_4 = 8'h99,
NUM_5 = 8'h92,
NUM_6 = 8'h82,
NUM_7 = 8'hF8,
NUM_8 = 8'h80,
NUM_9 = 8'h90,
NUM_A = 8'h88,
NUM_B = 8'h83,
NUM_C = 8'hC6,
NUM_D = 8'hA1,
NUM_E = 8'h86,
NUM_F = 8'h8E,
LIT_ALL = 8'h00,
BLC_ALL = 8'hFF;
parameter CNT_REF = 25'd1000;
reg [9:0] cnt_20us; //20us计数器
reg [3:0] data_tmp; //用于取出不同位选的显示数据
// assign dis_data = 32'hABCD_4413;
//描述位选信号切换
//描述刷新计数器
[email protected](posedge clk or negedge rst_n)begin
if(!rst_n)begin
cnt_20us <= 25'd0;
end
else if(cnt_20us >= CNT_REF - 25'd1)begin
cnt_20us <= 25'd0;
end
else begin
cnt_20us <= cnt_20us + 25'd1;
end
end
[email protected](posedge clk or negedge rst_n)begin
if(!rst_n)begin
dig_sel <= 8'hfe;//8'b1111_1110
end
else if(cnt_20us >= CNT_REF - 25'd1)begin
dig_sel <= {
dig_sel[6:0],dig_sel[7]};
end
else begin
dig_sel <= dig_sel;
end
end
//段选信号描述
[email protected](posedge clk or negedge rst_n)begin
if(!rst_n)begin
data_tmp <= 4'd0;
end
else begin
case(dig_sel)
8'b1111_1110:data_tmp <= dis_data[ 3-:4];
8'b1111_1101:data_tmp <= dis_data[ 7-:4];
8'b1111_1011:data_tmp <= dis_data[11-:4];
8'b1111_0111:data_tmp <= dis_data[15-:4];
8'b1110_1111:data_tmp <= dis_data[19-:4];
8'b1101_1111:data_tmp <= dis_data[23-:4];
8'b1011_1111:data_tmp <= dis_data[27-:4];
8'b0111_1111:data_tmp <= dis_data[31-:4];
default: data_tmp <= 4'hF;
endcase
end
end
[email protected](posedge clk or negedge rst_n)begin
if(!rst_n)begin
dig_seg <= BLC_ALL;
end
else begin
case(data_tmp)
4'h0 : dig_seg <= NUM_0;
4'h1 : dig_seg <= NUM_1;
4'h2 : dig_seg <= NUM_2;
4'h3 : dig_seg <= NUM_3;
4'h4 : dig_seg <= NUM_4;
4'h5 : dig_seg <= NUM_5;
4'h6 : dig_seg <= NUM_6;
4'h7 : dig_seg <= NUM_7;
4'h8 : dig_seg <= NUM_8;
4'h9 : dig_seg <= NUM_9;
4'hA : dig_seg <= NUM_A;
4'hB : dig_seg <= NUM_B;
4'hC : dig_seg <= NUM_C;
4'hD : dig_seg <= NUM_D;
4'hE : dig_seg <= NUM_E;
4'hF : dig_seg <= NUM_F;
default: ;
endcase
end
end
endmodule
仿真验证
`timescale 1ns/1ns
module tb_dig;
reg clk;
reg rst_n;
wire [7:0] dig_sel;
wire [7:0] dig_seg;
reg [39:0] CHARAC;//1个 ASCII 码,需要8bit 二进制表示
defparam seg_driver.CNT_REF = 100;
localparam
NUM_0 = 8'hC0,
NUM_1 = 8'hF9,
NUM_2 = 8'hA4,
NUM_3 = 8'hB0,
NUM_4 = 8'h99,
NUM_5 = 8'h92,
NUM_6 = 8'h82,
NUM_7 = 8'hF8,
NUM_8 = 8'h80,
NUM_9 = 8'h90,
NUM_A = 8'h88,
NUM_B = 8'h83,
NUM_C = 8'hC6,
NUM_D = 8'hA1,
NUM_E = 8'h86,
NUM_F = 8'h8E;
[email protected](*)begin
case(dig_seg)
NUM_0 : CHARAC = "NUM_0";
NUM_1 : CHARAC = "NUM_1";
NUM_2 : CHARAC = "NUM_2";
NUM_3 : CHARAC = "NUM_3";
NUM_4 : CHARAC = "NUM_4";
NUM_5 : CHARAC = "NUM_5";
NUM_6 : CHARAC = "NUM_6";
NUM_7 : CHARAC = "NUM_7";
NUM_8 : CHARAC = "NUM_8";
NUM_9 : CHARAC = "NUM_9";
NUM_A : CHARAC = "NUM_A";
NUM_B : CHARAC = "NUM_B";
NUM_C : CHARAC = "NUM_C";
NUM_D : CHARAC = "NUM_D";
NUM_E : CHARAC = "NUM_E";
NUM_F : CHARAC = "NUM_F";
default : CHARAC = "NUM_0";
endcase
end
seg_driver seg_driver(
/*input */.clk (clk ),
/*input */.rst_n (rst_n ),
/*output reg[7:0] */.dig_sel (dig_sel),
/*output reg[7:0] */.dig_seg (dig_seg)
);
initial clk = 1'b0;
always #10 clk = ~clk;
initial begin
rst_n = 1'b0;
#36 rst_n = 1'b1;
wait (seg_driver.lut == 15);
#(20 * seg_driver.CNT_REF * 3);
$stop(2);
end
endmodule
3.3.3、顶层文件
顶层文件在此不作讲解,根据下列RTL视图,相信读者可以很轻易的完成相应代码设计
RTL视图
3.4、板级验证
可以看到数码管由32‘h11111111每次自增1,在数据生成模块中可以调整变化速率。
4、总结
本设计实现了基本的字符显示,动态扫描
大家可以基于自己的理解完成秒表、数字钟之类的设计,相信聪明的你一定可以,加油!
边栏推荐
- 2022年7月10日“五心公益”活动通知+报名入口(二维码)
- Seata 1.3.0 four modes to solve distributed transactions (at, TCC, Saga, XA)
- Cmake learning manual
- Static semantic check of clang tidy in cicd
- Introduction to shell programming
- 2021-04-23
- Realize ray detection, drag the mouse to move the object and use the pulley to scale the object
- QT document
- [machine learning 03] Lagrange multiplier method
- From pornographic live broadcast to live broadcast E-commerce
猜你喜欢
When do you usually get grades in the soft exam? Online pedaling?
Seata 1.3.0 four modes to solve distributed transactions (at, TCC, Saga, XA)
How much review time does it usually take to take the intermediate soft exam?
高级软考(网络规划设计师)该如何备考?
Interprocess communication (IPC)
[untitled]
Transaction rolled back because it has been marked as rollback-only解决
深入理解Apache Hudi异步索引机制
Unable to open kernel device '\.\vmcidev\vmx': operation completed successfully. Reboot after installing vmware workstation? Module "devicepoweron" failed to start. Failed to start the virtual machine
How to prepare for the advanced soft test (network planning designer)?
随机推荐
shardingsphere分库分表示例(逻辑表,真实表,绑定表,广播表,单表)
Static semantic check of clang tidy in cicd
The gun startles the dragon, and the crowd "locks" Zhou Zhi
Get pictures through opencv, change channels and save them
JS implementation chain call
PHP \ newline cannot be output
CSAPP bomb lab parsing
Cluster task scheduling system lsf/sge/slurm/pbs based on HPC scenario
Some online academic report websites and machine learning videos
Go-Redis 中间件
【pyqt】tableWidget里的cellWidget使用信号与槽机制
中级网络工程师是什么?主要是考什么,有什么用?
Unity determines whether the mouse clicks on the UI
Find the greatest common divisor and the least common multiple (C language)
Mpx 插件
Template initial level template
Galaxy Kirin desktop operating system installation postgresql13 (source code installation)
软考中级,软件设计师考试那些内容,考试大纲什么的?
[STM32] actual combat 3.1 - drive 42 stepper motors with STM32 and tb6600 drivers (I)
变量的解构赋值