23- 数码管动态显示02-转换BCD码
1.BCD码
- 数码管动态显示的data[19:0]使用二进制数表示的多位十进制数,不能直接生成段选和片选信号,需要使用BCD码表示的十进制数
- BCD码(Binary-Coded Decimal),又称为二-十进制码,使用四位二进制数来表示1位十进制数中的0-9这十个数,是一种二进制的数字编码形式,用二进制编码的十进制代码
- 分类:有权码和无权码,这里的权字表示权值,有权码四位二进制数中的
- 有权码:8421码,5421码,2421码
- 无权码:余三码,余三循环码,格雷码

- 使用多位数码管表示234,二进制表示就是1110_1010,使用8421码表示0010_0011_0100
- 使用多位数码管显示234,需要使用动态扫描的方式,要依次显示个位,十位,百位,要求能从传入的数据中得到个位,十位,百位,所以使用BCD码可以直接得到位选信号和段选信号
1.1 二进制数转换为BCD码

- 实现转换的第一步,就是在输入的二进制码之前补多少个0,补(十进制数位数*4)个0
- 234 -- 前面补12个0,然后看BCD码每一位,如果小于等于4,就保持不变,进行移位操作(左移);如果大于4,就将补的BCD码进行加3
- 直到二进制数为0,补充的BCD码位就是对应的二进制数的BCD码,十进制数-->二进制数-->BCD码
- 移位次数:输入多少位二进制数,就会移位多少次
2.BCD码转换模块
2.1 模块框图
添加BCD码转换模块
- 输入时钟和复位信号
- 输入十进制数的二进制编码
- 输出六路BCD码4bit,输出的6路BCD码分别用个位,十位,百位,千位,万位,十万位表示

系统框图需要进行修改

2.2 波形图
- 二进制码向BCD码的转换是通过判断运算加移位操作实现的,移位次数是与二进制数的位数相关的,需要移位计数器对于判断运算和移位次数进行计数,移位次数是20次,所以位宽为5bit
- 需要一个中间变量存储中间的数据,data_shift[43:0],(二进制数位数+BCD码位数)
- 判断运算在前,移位操作在后,需要一个标志信号区分这两个操作(shift_flag),但是这两个操作是在一个时钟周期内完成的,每次移位操作都是在判断计算之后进行的

2.3 RTL
module bcd_8421(
input wire sys_clk,
input wire sys_rst_n,
input wire [19:0] data,
output reg [3:0] unit ,
output reg [3:0] ten ,
output reg [3:0] hun ,
output reg [3:0] thou ,
output reg [3:0] t_thou ,
output reg [3:0] h_hun ,
);
reg [4:0] cnt_shift;
reg [43:0] data_shift;
reg shift_flag;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_clk == 1'b1)
cnt_shift <= 5'd0;
else if((cnt_shift == 5'd21)&&(shift_flag == 1'b1))
cnt_shift <= 5'd0;
else if(shift_flag == 1'b1)
cnt_shift <= cnt_shift + 1'b1;
else
cnt_shift <= cnt_shift;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_clk == 1'b1)
data_shift <= 44'b0;
else if(cnt_shift == 5'd0)
data_shift <= {24'b0,data};
else if((shift_flag == 1'b0) && (cnt_shift <= 20))
begin
data_shift[23:20] <= (data_shift[23:20] > 4) ? (data_shift[23:20] + 2'd3) : data_shift[23:20];
data_shift[27:24] <= (data_shift[27:24] > 4) ? (data_shift[27:24] + 2'd3) : data_shift[27:24];
data_shift[31:28] <= (data_shift[31:28] > 4) ? (data_shift[31:28] + 2'd3) : data_shift[31:28];
data_shift[35:32] <= (data_shift[35:32] > 4) ? (data_shift[35:32] + 2'd3) : data_shift[35:32];
data_shift[39:36] <= (data_shift[39:36] > 4) ? (data_shift[39:36] + 2'd3) : data_shift[39:36];
data_shift[43:40] <= (data_shift[43:40] > 4) ? (data_shift[43:40] + 2'd3) : data_shift[43:40];
end
else if((shift_flag == 1'b1)&&(cnt_shift <= 20))
data_shift <= data_shift << 1;
else
data_shift <= data_shift;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_clk == 1'b1)
shift_flag <= 1'b0;
else
shift_flag <= ~shift_flag;
// 输出信号
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_clk == 1'b1)
begin
unit <= 4'b0;
ten <= 4'b0;
hun <= 4'b0;
thou <= 4'b0;
t_thou <= 4'b0;
h_hun <= 4'b0;
end
else if(data_shift == 5'd21)
begin
unit <= data_shift[23:20];
ten <= data_shift[27:24];
hun <= data_shift[31:28];
thou <= data_shift[35:32];
t_thou <= data_shift[39:36];
h_hun <= data_shift[43:40];
end
endmodule
2.4 Testbench
`timescale 1ns/1ns
module tb_bcd_8421();
reg sys_clk ;
reg sys_rst_n ;
reg [19:0] data ;
wire [3:0] unit ;
wire [3:0] ten ;
wire [3:0] hun ;
wire [3:0] thou ;
wire [3:0] t_thou ;
wire [3:0] h_hun ;
initial begin
sys_clk = 1'b1;
sys_rst_n <= 1'b0;
data <= 20'd0;
#30
sys_rst_n <= 1'b1;
data <= 20'd123_456;
#3000;
data <= 20'd654_321;
#3000;
data <= 20'd987_654;
#2000;
data <= 20'd999_999;
end
always #10 sys_clk = ~sys_clk;
bcd_8421 bcd_8421_inst(
.sys_clk (sys_clk ) ,
.sys_rst_n (sys_rst_n ) ,
.data (data ) ,
.unit (unit ) ,
.ten (ten ) ,
.hun (hun ) ,
.thou (thou ) ,
.t_thou (t_thou ) ,
.h_hun (h_hun ) ,
);
endmodule
2.5 仿真
23- 数码管动态显示02-转换BCD码的更多相关文章
- Delphi中对BCD码的直接支持 (转)
最近在Delphi下写软件,需要将数据转换为BCD码和将BCD码转换为其它数据类型,从网上搜索了一下,没有发现好的函数,于是就想自定义函数来完成BCD与其它格式的数据转换功能.但最终没有动手写,先查查 ...
- FPGA中将十进制数在数码管中显示(verilog版)--二进制转换为BCD码
这周有朋友问怎样在fpga中用数码管来显示一个十进制数,比如1000.每个数码管上显示一位十进制数.如果用高级语言来分离各位,只需要分别对该数做1000,100,10对应的取商和取余即可分离出千百十个 ...
- Linux时间戳转换成BCD码(转载)
#include <stdio.h> #include <stdlib.h> #include <time.h> #include <math.h> / ...
- C#下16进制和BCD码转换代码
private static Byte[] ConvertFrom(string strTemp) { try { if (Convert.ToBoolean(strTemp.Length & ...
- 二进制 转换成十进制 BCD码(加3移位法)
"原来的二进制数十几位,则左移时就要左移几位" "二进制数调整BCD码的方法是将二进制码左移8次,每次移位后都检查低四位LSD+3是否大于7,如是则加3,否则不加,高4位 ...
- 一种BCD码转换的算法
#include "stdio.h" typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef ...
- C语言之linux内核--BCD码转二进制与二进制转BCD码(笔试经典)
在分析代码之前,我们先来了解一下,BCD码和二进制到底区别在哪? 学习过计算机原理的和数字电子技术这两门课的都会知道这两个到底是什么含义,也有的同学学过了,考过了,过了一段时间又忘记了,今天,我们通过 ...
- 基于Verilog HDL的二进制转BCD码实现
在项目设计中,经常需要显示一些数值,比如温湿度,时间等等.在数字电路中数据都是用二进制的形式存储,要想显示就需要进行转换,对于一个两位的数值,对10取除可以得到其十位的数值,对10取余可以得到个位的数 ...
- BCD码
BCD码(Binary-Coded Decimal)亦称二进码十进数或二-十进制代码,是用4位二进制数来表示1位十进制数中的0~9这10个数码,用一种使用二进制编码十进制的数字编码形式.BCD码这种 ...
- BCD码、十六进制与十进制互转
在做嵌入式软件的设计中,常常会遇到十六进制.BCD码与十进制之间的转换,近期做M1卡的应用中,涉及了大量的十六进制.BCD码与十进制之间的转换.通过对BCD码.十六进制 权的理解,轻松的实现了他们之间 ...
随机推荐
- Ascii字符画 在线生成工具
英文 http://patorjk.com/software/taag/ 点击 Test All 一键测试所有样式 目前有317种可选 个人常用格式 3D-ASCII ANSI Shadow Bulb ...
- MYSQL数据库root账户密码忘记,如何重置?
- 牛客刷java记录第5天
第一题,下列代码运行结果是? class X { Y y = new Y(); public X() { System.out.print("X"); } } class Y { ...
- ElasticSearch之Index stats API
获取指定索引的统计数据. 获取指定索引的全部统计数据,命令样例如下: curl -X GET "https://localhost:9200/testindex_001/_stats?pre ...
- CentOS基线检测脚本
本脚本适用于CentOS 7.5-7.9版本,其他版本不详 1.检查系统信息 查看代码 echo " " echo "########################## ...
- Centos7——防火墙(Firewall)命令
centos防火墙根据系统大致有2种,一种是centos6时代的iptables:一种是centos7时代的firewalld: CentOS 7中防火墙是一个非常的强大的功能,在CentOS 6.5 ...
- Java反序列化漏洞-CC1利用链分析
@ 目录 一.前置知识 1. 反射 2. Commons Collections是什么 3. 环境准备 二.分析利用链 1. Transformer 2. InvokeTransformer 执行命令 ...
- wangEditor出现初始化编辑器时候未传入任何参数,请查阅文档
wangEditor出现初始化编辑器时候未传入任何参数,请查阅文档 出现的原因可能是你未在初始视图.元素未创建.created.模态框.弹窗.抽屉中使用,你应该在div元素创建了再执行初始渲染, 解决 ...
- 教你使用Jupyter可视化查询语句的语法树
摘要:本文以华为图引擎使用的cypher查询语言为例,将查询语句的解析结果(语法树)在jupyterLab上可视化. 本文分享自华为云社区<使用Jupyter可视化查询语句的语法树--以图查询语 ...
- 如何做好分支管理,保证高效CI/CD?
摘要:一文讲述git分支管理策略. 本文分享自华为云社区<如何做好分支管理,保证高效CICD?>,作者:华为云PaaS服务小智. 引言 CI/CD是DevOps 的基础核心,做好CI/CD ...