17 ABCD数码管显示与动态扫描原理

1. 驱动八位数码管循环点亮

1.1 数码管结构图

数码管有两种结构,共阴极和共阳极,ACX720板上的是共阳极数码管,低电平点亮。

1.2 三位数码管等效电路图

为了节约I/O接口,各个数码管的各段发光管被连在一起,通过sel端口选择要发光的数码管。

1.3 单个数码管发光的LUT(look up table)

2.  数码管显示与动态扫描逻辑建模

3. 数码管显示与动态扫描的Verilog实现

3.1 不完善的设计代码版本

1. 设计代码

该设计代码有两个地方需要修改

  1. 分频时钟的使用不合理,在fpga设计中,一定要避免使用计数器(寄存器)分频得到的信号来作为时钟再去驱动其他的寄存器;推荐使用使能时钟,不要使用门控时钟。
  2. 在fpga设计中,推荐多使用时序逻辑而非组合逻辑。对于case语句,我们要将其放在always语句块中,在每个时钟沿下发生数据的变换。
module hex8(
    clk,
    rstn,
    disp_data,
    sel,
    led
);
    
    parameter times = 25000; // 0.5ms
    input clk;
    input rstn;
    input [31:0]disp_data;
    output reg [7:0] sel;
    output reg [7:0] led;
    
    reg [15:0]div_cnt;
    always@(posedge clk or negedge rstn)
    if(!rstn)
        div_cnt <= 0;
    else if(div_cnt >= times - 1)
        div_cnt <= 0;
    else
        div_cnt <= div_cnt + 1'd1;
     
    //分频时钟
    //用一个寄存器来模拟一个时钟去驱动其他寄存器会存在许多问题
    reg clk_lk;
    always@(posedge clk or negedge rstn)
    if(!rstn)
        clk_lk <= 0;
    else if(div_cnt == times - 1)
        clk_lk <= ~clk_lk;
    
    //cnt累加器
    reg [2:0] num_cnt;    
    always@(posedge clk_lk or negedge rstn)
    if(!rstn)
        num_cnt <= 0;
    else
        num_cnt <= num_cnt + 1'd1;
    
    //三八译码器    
    always@(posedge clk_lk or negedge rstn)
    if(!rstn)
        sel <= 0;
    else case(num_cnt)
        0:sel = 8'b0000_0001;
        1:sel = 8'b0000_0010;
        2:sel = 8'b0000_0100;
        3:sel = 8'b0000_1000;
        4:sel = 8'b0001_0000;
        5:sel = 8'b0010_0000;
        6:sel = 8'b0100_0000;
        7:sel = 8'b1000_0000;
    endcase
   
    //八选一多路器
    reg [3:0]disp_tmp;
    always@(*)
    case(num_cnt)
        0:disp_tmp = disp_data[3:0];
        1:disp_tmp = disp_data[7:4];
        2:disp_tmp = disp_data[11:8];
        3:disp_tmp = disp_data[15:12];
        4:disp_tmp = disp_data[19:16];
        5:disp_tmp = disp_data[23:20];
        6:disp_tmp = disp_data[27:24];
        7:disp_tmp = disp_data[31:28];
    endcase
    
    //四十六译码器 
    always@(*)
    case(disp_tmp)
        0:led = 8'hc0;
        1:led = 8'hf9;
        2:led = 8'ha4;
        3:led = 8'hb0;
        4:led = 8'h99;
        5:led = 8'h92;
        6:led = 8'h82;
        7:led = 8'hf8;
        8:led = 8'h80;
        9:led = 8'h90;
        4'ha:led = 8'h88;
        4'hb:led = 8'h83;
        4'hc:led = 8'hc6;
        4'hd:led = 8'ha1;
        4'he:led = 8'h86;
        4'hf:led = 8'h8e;  
        default:led = 8'hc0;
    endcase

endmodule

2. 仿真波形

3.1 修改分频时钟和case语句后的设计代码

1. 设计代码

module hex8_2(
    clk,
    rstn,
    disp_data,
    sel,
    led
);
    
    parameter times = 50000; // 1ms
    input clk;
    input rstn;
    input [31:0]disp_data;
    output reg [7:0] sel;
    output reg [7:0] led;
    
    reg [15:0]div_cnt;
    always@(posedge clk or negedge rstn)
    if(!rstn)
        div_cnt <= 0;
    else if(div_cnt >= times - 1)
        div_cnt <= 0;
    else
        div_cnt <= div_cnt + 1'd1;
     
    //使能时钟  
    reg clk_lk;
    always@(posedge clk or negedge rstn)
    if(!rstn)
        clk_lk <= 0;
    else if(div_cnt == times - 1)
        clk_lk <= 1'd1;
    else
        clk_lk <= 0;
    
    //cnt累加器
    reg [2:0] num_cnt;    
    always@(posedge clk_lk or negedge rstn)
    if(!rstn)
        num_cnt <= 0;
    else if(clk_lk == 1)
        num_cnt <= num_cnt + 1'd1;
    
    //三八译码器    
    always@(posedge clk or negedge rstn)
    if(!rstn)
        sel <= 0;
    else case(num_cnt)
        0:sel = 8'b0000_0001;
        1:sel = 8'b0000_0010;
        2:sel = 8'b0000_0100;
        3:sel = 8'b0000_1000;
        4:sel = 8'b0001_0000;
        5:sel = 8'b0010_0000;
        6:sel = 8'b0100_0000;
        7:sel = 8'b1000_0000;
    endcase
   
    //八选一多路器
    reg [3:0]disp_tmp;
    always@(posedge clk)
    case(num_cnt)
        0:disp_tmp = disp_data[3:0];
        1:disp_tmp = disp_data[7:4];
        2:disp_tmp = disp_data[11:8];
        3:disp_tmp = disp_data[15:12];
        4:disp_tmp = disp_data[19:16];
        5:disp_tmp = disp_data[23:20];
        6:disp_tmp = disp_data[27:24];
        7:disp_tmp = disp_data[31:28];
    endcase
    
    //四十六译码器 
    always@(posedge clk)
    case(disp_tmp)
        0:led = 8'hc0;
        1:led = 8'hf9;
        2:led = 8'ha4;
        3:led = 8'hb0;
        4:led = 8'h99;
        5:led = 8'h92;
        6:led = 8'h82;
        7:led = 8'hf8;
        8:led = 8'h80;
        9:led = 8'h90;
        4'ha:led = 8'h88;
        4'hb:led = 8'h83;
        4'hc:led = 8'hc6;
        4'hd:led = 8'ha1;
        4'he:led = 8'h86;
        4'hf:led = 8'h8e;  
        default:led = 8'hc0;
    endcase

endmodule

2.仿真代码

module hex8_2(
    clk,
    rstn,
    disp_data,
    sel,
    led
);
    
    parameter times = 50000; // 1ms
    input clk;
    input rstn;
    input [31:0]disp_data;
    output reg [7:0] sel;
    output reg [7:0] led;
    
    reg [15:0]div_cnt;
    always@(posedge clk or negedge rstn)
    if(!rstn)
        div_cnt <= 0;
    else if(div_cnt >= times - 1)
        div_cnt <= 0;
    else
        div_cnt <= div_cnt + 1'd1;
     
    //使能时钟  
    reg clk_lk;
    always@(posedge clk or negedge rstn)
    if(!rstn)
        clk_lk <= 0;
    else if(div_cnt == times - 1)
        clk_lk <= 1'd1;
    else
        clk_lk <= 0;
    
    //cnt累加器
    reg [2:0] num_cnt;    
    always@(posedge clk_lk or negedge rstn)
    if(!rstn)
        num_cnt <= 0;
    else if(clk_lk == 1)
        num_cnt <= num_cnt + 1'd1;
    
    //三八译码器    
    always@(posedge clk or negedge rstn)
    if(!rstn)
        sel <= 0;
    else case(num_cnt)
        0:sel = 8'b0000_0001;
        1:sel = 8'b0000_0010;
        2:sel = 8'b0000_0100;
        3:sel = 8'b0000_1000;
        4:sel = 8'b0001_0000;
        5:sel = 8'b0010_0000;
        6:sel = 8'b0100_0000;
        7:sel = 8'b1000_0000;
    endcase
   
    //八选一多路器
    reg [3:0]disp_tmp;
    always@(posedge clk)
    case(num_cnt)
        0:disp_tmp = disp_data[3:0];
        1:disp_tmp = disp_data[7:4];
        2:disp_tmp = disp_data[11:8];
        3:disp_tmp = disp_data[15:12];
        4:disp_tmp = disp_data[19:16];
        5:disp_tmp = disp_data[23:20];
        6:disp_tmp = disp_data[27:24];
        7:disp_tmp = disp_data[31:28];
    endcase
    
    //四十六译码器 
    always@(posedge clk)
    case(disp_tmp)
        0:led = 8'hc0;
        1:led = 8'hf9;
        2:led = 8'ha4;
        3:led = 8'hb0;
        4:led = 8'h99;
        5:led = 8'h92;
        6:led = 8'h82;
        7:led = 8'hf8;
        8:led = 8'h80;
        9:led = 8'h90;
        4'ha:led = 8'h88;
        4'hb:led = 8'h83;
        4'hc:led = 8'hc6;
        4'hd:led = 8'ha1;
        4'he:led = 8'h86;
        4'hf:led = 8'h8e;  
        default:led = 8'hc0;
    endcase

endmodule

3.仿真波形

 4. 使能时钟与门控时钟的原理和差异

1. 使能时钟和门控时钟

  • 使用门控时钟时:将一个D触发器的输出作为其他D触发器的时钟输入,忽略ENA。

  • 使用使能时钟时:D触发器的工作时钟仍为高质量的全局时钟,利用使能时钟使能D触发器。

2. 使用全局时钟的原因

  • 全局时钟是一条“高速公路”,时钟信号到达各个寄存器的时间受连线距离影响比较小,而用寄存器产生的门控时钟,走的是内部连线,随着距离的延长,延迟增加明显,从而破环寄存器的建立保持时间。
  • 使用寄存器传输时钟信号时,随着寄存器一级一级的传递,信号会出现波动,时钟信号的波形会越来越差(毛刺,波动等)
  • 全局时钟有专门的晶体管来提高时钟的驱动能力,而寄存器产生的时钟会随着寄存器的传递,驱动能力越来越弱。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/386290.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Spring框架】Spring事务同步

目录 一、什么是Spring事务同步 二、 事务同步管理器 2.1 TransactionSynchronizationManager事务同步管理器 2.1.1 资源同步 2.1.2 事务同步 2.1.3 总结 三、事务同步管理器保障事务的原理 四、spring事务为何使用TransactionSynchronizationManager spring源码实现 …

详解CC++内存管理(new和delete)

文章目录 写在前面1. C&C内存分布2. C语言中动态内存管理方式&#xff1a;malloc/calloc/realloc/free3. C内存管理方式&#xff08;语法&#xff09;3.1 new/delete操作内置类型3.2 new和delete操作自定义类型 4. new和delete的实现原理4.1 operator new与operator delete…

企业架构师的人格特质

L - Learning 持续学习的能力A - Abstracting 概念抽象的能力C1 - Connecting 联结事物的能力C2 - Compromising 平衡折衷的能力D - Decisioning 果断决策的能力 参考文章的链接

再利用系统盘时,如何删除恢复分区(Recovery Partition)

系统盘有一个Recovery Partition&#xff0c;记录了重要的系统信息&#xff0c;不能删除。 Windows 10的 Disk Managment 不提供用户删除这个Partition的选项。 近日我插入一块原系统盘&#xff0c;Format后作为DataDisk&#xff0c;此时需要删除这块硬盘上的RecoveryPartition…

Redis中内存淘汰算法实现

Redis中内存淘汰算法实现 Redis的maxmemory支持的内存淘汰机制使得其成为一种有效的缓存方案&#xff0c;成为memcached的有效替代方案。 当内存达到maxmemory后&#xff0c;Redis会按照maxmemory-policy启动淘汰策略。 Redis 3.0中已有淘汰机制&#xff1a; noevictionall…

配置 JDK 环境变量(最简单)

前言 在通过控制台使用 javac 命令编译 &#xff0c;java 命令运行 Java 程序时&#xff0c;会出现识别不了这两个命令的情况&#xff0c;如下所示&#xff1a; 这是没有配置环境变量导致的 在控制台输入的命令&#xff0c;操作系统会去一些特定的目录中去找&#xff0c;看看是…

HCIA-HarmonyOS设备开发认证V2.0-轻量系统内核内存管理-动态内存

目录 一、动态内存运行机制二、动态内存开发流程三、动态内存使用说明四、动态内存核心算法五、动态内存接口六、代码分析&#xff08;待续...&#xff09;坚持就有收获 一、动态内存运行机制 动态内存管理&#xff0c;即在内存资源充足的情况下&#xff0c;根据用户需求&…

漫漫数学之旅019

文章目录 经典格言数学习题古今评注名人小传 - 大卫希尔伯特 经典格言 没有人能够把我们从康托为我们创造的乐园中驱逐出去。——大卫希尔伯特&#xff08;David Hilbert&#xff09; 大卫希尔伯特&#xff0c;这位数学界的“顽皮大亨”&#xff0c;曾经用一种近乎宣誓的方式来…

更新至2022年,各省人口高质量城镇化指标体系构建原始数据(13个指标)

更新至2022年&#xff0c;各省人口高质量城镇化指标体系构建原始数据 1、时间&#xff1a;更新至2022年&#xff0c;具体每个指标时间见下文 2、来源&#xff1a;整理自国家统计局、统计年鉴 3、范围&#xff1a;31省市 4、指标&#xff1a; 2008-2022年每十万人口高等学校…

【QT+QGIS跨平台编译】之三十六:【RasterLite2+Qt跨平台编译】(一套代码、一套框架,跨平台编译)

文章目录 一、RasterLite2介绍二、文件下载三、文件分析四、pro文件五、编译实践一、RasterLite2介绍 RasterLite2是一个开源的轻量级栅格数据库,可以用于存储和管理各种类型的栅格数据,包括卫星遥感图像、数字高程模型等。 与传统的GIS数据存储方式不同,RasterLite2采用基…

Swift Combine 有序的异步操作 从入门到精通十二

Combine 系列 Swift Combine 从入门到精通一Swift Combine 发布者订阅者操作者 从入门到精通二Swift Combine 管道 从入门到精通三Swift Combine 发布者publisher的生命周期 从入门到精通四Swift Combine 操作符operations和Subjects发布者的生命周期 从入门到精通五Swift Com…

零基础学编程怎么入手,中文编程工具构件箱之星空构件用法教程,系统化的编程视频教程上线

零基础学编程怎么入手&#xff0c;中文编程工具构件箱之星空构件用法教程&#xff0c;系统化的编程视频教程上线 一、前言 今天给大家分享的中文编程开发语言工具资料如下&#xff1a; 编程入门视频教程链接 http://​ https://edu.csdn.net/course/detail/39036 ​ 编程…

C++笔记:类与对象的语法

文章目录 1 简单认识面向过程与面向对象1.1 面向过程1.2 面向对象 2 类的引入&#xff1a;struct -> class3 类的定义3.1 class 定义类的语法3.2 成员变量的命名建议 4 类的访问限定符4.1 class 和 struct 的区别4.2 C更喜欢用class定义类的原因 5 类的作用域5.1 声明定义合…

openGauss学习笔记-218 openGauss性能调优-确定性能调优范围-硬件瓶颈点分析-I/O

文章目录 openGauss学习笔记-218 openGauss性能调优-确定性能调优范围-硬件瓶颈点分析-I/O218.1 查看I/O状况218.2 性能参数分析 openGauss学习笔记-218 openGauss性能调优-确定性能调优范围-硬件瓶颈点分析-I/O 获取openGauss节点的CPU、内存、I/O和网络资源使用情况&#xf…

HTML世界之第二重天

目录 一、HTML 格式化 1.HTML 文本格式化标签 2.HTML "计算机输出" 标签 3.HTML 引文, 引用, 及标签定义 二、HTML 链接 1.HTML 链接 2.HTML 超链接 3.HTML 链接语法 4.文本链接 5.图像链接 6.锚点链接 7.下载链接 8.Target 属性 9.Id 属性 三、HTML …

Blazor OIDC 单点登录授权实例5 - 独立SSR App (net8 webapp ) 端授权

目录: OpenID 与 OAuth2 基础知识Blazor wasm Google 登录Blazor wasm Gitee 码云登录Blazor OIDC 单点登录授权实例1-建立和配置IDS身份验证服务Blazor OIDC 单点登录授权实例2-登录信息组件wasmBlazor OIDC 单点登录授权实例3-服务端管理组件Blazor OIDC 单点登录授权实例4 …

虚拟人专题报告:虚拟人深度产业分析报告

今天分享的是虚拟人系列深度研究报告&#xff1a;《虚拟人专题报告&#xff1a;虚拟人深度产业分析报告》。 &#xff08;报告出品方&#xff1a;Q量子位&#xff09; 报告共计&#xff1a;18页 技术背景 虚拟数字人指存在于非物理世界中&#xff0c;由计算机图形学、图形渲…

Waymo数据集下载与使用

在撰写论文时&#xff0c;接触到一个自动驾驶数据集Waymo Dataset 论文链接为&#xff1a;https://arxiv.org/abs/1912.04838v7 项目链接为&#xff1a;https://github.com/waymo-research/waymo-open-dataset 数据集链接为&#xff1a;https://waymo.com/open waymo提供了两种…

WordPress每天发布60s插件

源码名称:WordPress每天发布60s插件 适用平台:WordPress Wordpress还是比较适合个人博客网站&#xff0c;这个60秒插件适合一些喜欢自动发新闻早报晚报人员。 wordpress一直以来都是建立个人博客网站比较适合的脚手架&#xff0c;非常合适个人使用。 小程序源码就找 源码软件…

【小赛1】蓝桥杯双周赛第5场(小白)思路回顾

我的成绩&#xff1a;小白(5/6) 完稿时间&#xff1a;2024-2-13 比赛地址&#xff1a;https://www.lanqiao.cn/oj-contest/newbie-5/ 相关资料&#xff1a; 1、出题人题解&#xff1a;“蓝桥杯双周赛第5次强者挑战赛/小白入门赛”出题人题解 - 知乎 (zhihu.com) 2、矩阵快速幂&…