浅谈BCD码同二进制转换

article/2025/10/26 8:46:08

浅谈BCD码同二进制转换

  • 一、BCD码
    • 1、BCD码概述
    • 2、BCD分类
      • 1、有权码
      • 2、无权码
    • 3、BCD运算问题
  • 二、二进制BCD码
    • 1、原理实现
    • 2、模块划分
    • 3、仿真调试
    • 4、仿真验证
  • 三、BCD码转二进制
    • 1、原理实现
    • 2、模块划分
    • 3、仿真验证

一、BCD码

1、BCD码概述

  • BCD码(Binary-Coded Decimal‎),用4位二进制数来表示1位十进制数中的0~9这10个数码,是一种二进制的数字编码形式,用二进制编码的十进制代码。BCD码这种编码形式利用了四个位元来储存一个十进制的数码,使二进制和十进制之间的转换得以快捷的进行。
  • 相对于一般的浮点式记数法,采用BCD码,既可保存数值的精确度,又可免去使计算机作浮点运算时所耗费的时间
  • BCD码也称二进码十进数,BCD码可分为有权码和无权码两类。其中,常见的有权BCD码有8421码、2421码、5421码,无权BCD码有余3码、余3循环码、格雷码。

图片表示
在这里插入图片描述

流程详解:
二进制数:1010 0010 = 2 5 + 2 7 + 2 1 = 2 + 32 + 128 = 162 2^5+2^7+2^1=2+32+128=162 25+27+21=2+32+128=162
BCD码是用四位二进制数表示十进制数【0~9】
0001 = 2 0 = 1 2^0=1 20=1
0110= 2 2 + 2 1 = 6 2^2+2^1=6 22+21=6
0010= 2 1 = 2 2^1=2 21=2

2、BCD分类

BCD码可分为有权码和无权码两类。其中,常见的有权BCD码有8421码、2421码、5421码,无权BCD码有余3码、余3循环码、格雷码

  • 有权码,自然二进制代码是按照二进制代码各位权值大小,以自然向下加一,逢二进一的方式来表示数值的大小所生成的代码。
  • 有权码和无权码区别是每一位是否有权值。

1、有权码

8421
8421 BCD码是最基本和最常用的BCD码,它和四位自然二进制码相似,各位的权值为8、4、2、1,故称为有权BCD码。和四位自然二进制码不同的是,它只选用了四位二进制码中前10组代码,即用0000~1001分别代表它所对应的十进制数,余下的六组代码不用。
运算规则:

十进制0123456789
二进制(BCD8421)0000000100100011010001010110011110001001
按权相加0 2 0 2^0 20 2 1 2^1 21 2 1 + 2 0 2^1+2^0 21+20 2 2 2^2 22 2 2 + 2 0 2^2+2^0 22+20 2 2 + 2 1 2^2+2^1 22+21 2 2 + 2 1 + 2 0 2^2+2^1+2^0 22+21+20 2 3 2^3 23 2 3 + 2 0 2^3+2^0 23+20

实例验证:

十进制数: 4 + 3 = 7 4+3=7 4+3=7
二进制数: 0100 + 0011 = 0111 0100+0011=0111 0100+0011=0111

/*二进制加法:逢二进一 */0 1 0 0    4+ 0 0 1 1    30 1 1 1    7

5421

十进制0123456789
二进制(BCD5421)0000000100100011010010001001101010111100

2421

十进制0123456789
二进制(BCD2421)0000000100100011010010111100110111101111

总结:
有权码就是对应数字为对应位的权值,1代表可以取到该值,0表示取不到。
8421:十进制数:5 二进制数:0101 即4和1能取到 4 + 1 = 5 4+1=5 4+1=5
5421: 十进制数:5 二进制数:1000 即5能取到 5 5 5
2421:十进制数:9 二进制数:1111即2和4和2和1都能取到 2 + 4 + 2 + 1 = 9 2+4+2+1=9 2+4+2+1=9

2、无权码

余三码
余3码是8421 BCD码的每个码组加3(0011)形成的。常用于BCD码的运算电路中。

十进制0123456789
二进制(BCD余三码)0011010001010110011110001001101010111100

实例验证:

十进制数:7
二进制数;0111
2 2 + 2 1 + 2 0 = 4 + 2 + 1 = 7 2^2+2^1+2^0=4+2+1=7 22+21+20=4+2+1=7

/*二进制加法:逢二进一 */0 1 1 1    7+ 0 0 1 1    31 0 1 0   余三码: 7  十进制数:10

余三循环码
余3循环码是无权码,即每个编码中的1和0没有确切的权值,整个编码直接代表一个数值。主要优点是相邻编码只有一位变化,避免了过渡码产生的“噪声”。

十进制0123456789
二进制(BCD余三循环码)0010011001110101010011001101111111101010

3、BCD运算问题

我们知道,BCD是用四位二进制数表示十进制数【0~9】的,而四位二进制数可以表示的十进制数为 2 4 = 16 2^4=16 24=16 个即【0~15】,当运算超出范围怎么办?
解决方案:
5 + 8 = 13 5+8=13 5+8=13为例
十进制数: 5 + 8 = 13 5+8=13 5+8=13
二进制数: 0101 + 1000 = 1101 0101+1000=1101 0101+1000=1101
差值: 16 − 10 = 6 16-10=6 1610=6
将所得值加6,产生进位,高位补0
1101 + 0110 = 00010011 1101+0110=00010011 1101+0110=00010011
在这里插入图片描述

/*二进制加法:逢二进一 */1 1 0 1    13+ 0 1 1 0    61  1          产生进位0 0 0 1  0 0 1 1    高位补0

二、二进制BCD码

1、原理实现

使用逐步移位法来实现二进制数向BCD码的转换;
变量定义:

  • B:需要转换的二进制数位宽
  • D:转换后的BCD码位宽(其中BCD码的位宽计算如下:根据二进制数的位宽,求出它的无符号数能表示的最大值和最小值,如数据位宽是8位则数据范围大小就是0~255,我们取最大值255,每一个数字对应4位BCD码,三个数字就对应3x4=12位的BCD码)
  • N:需要转换的二进制数位宽加上转换后的BCD码位宽

逐步移位法的规则:

  • 准备一个N比特的移位寄存器;
  • 二进数逐步左移;
  • 每次左移之后每个BCD位做大四加三的调整;
  • 二进数全部移完,得到结果。

移位流程表

移位次数BCD[11:8]BCD[7:4]BCD[3:0]bin[7:0]说明
010100101输入二进制数
1101001010左移一位,低位补0
21010010100左移两位,低位补0
310100101000101=5;大于4加3
3100000101000加3不移位
410000010100001000移位,原始值也移位,低位补0
510000010100000循环移位,低位补0
6100000101000000循环移位,低位补0
71000001010000000循环移位,低位补0
71011001010000000循环移位,低位补0
810110010100000000循环移位,低位补0
BCD165移位结束,输出BCD码

2、模块划分

顶层模块
在这里插入图片描述
代码实现

module bin2bcd (input         [7:0]       bin    ,//二进制输入output        [11:0]      bcd     //bcd码输出
);//信号定义wire        [19:0]         bcd_reg0  ;wire        [19:0]         bcd_reg1  ;wire        [19:0]         bcd_reg2  ;wire        [19:0]         bcd_reg3  ;wire        [19:0]         bcd_reg4  ;wire        [19:0]         bcd_reg5  ;wire        [19:0]         bcd_reg6  ;wire        [19:0]         bcd_reg7  ;wire        [19:0]         bcd_reg8  ;//八次移位结果输出assign bcd_reg0 = {12'b0000_0000_0000,bin};//将输入的八位二进制转换为二十位//第一次移位bcd_modify b1(.data_in(bcd_reg0),.data_out(bcd_reg1));//第二次移位bcd_modify b2(.data_in(bcd_reg1),.data_out(bcd_reg2));//第三次移位bcd_modify b3(.data_in(bcd_reg2),.data_out(bcd_reg3));//第四次移位bcd_modify b4(.data_in(bcd_reg3),.data_out(bcd_reg4));//第五次移位bcd_modify b5(.data_in(bcd_reg4),.data_out(bcd_reg5));//第六次移位bcd_modify b6(.data_in(bcd_reg5),.data_out(bcd_reg6));//第七次移位bcd_modify b7(.data_in(bcd_reg6),.data_out(bcd_reg7));//第八次移位bcd_modify b8(.data_in(bcd_reg7),.data_out(bcd_reg8));//BCD输出assign bcd = {bcd_reg8[19:8]};//取高12位为输出结果endmodule

移位模块
在这里插入图片描述
代码实现

//移位处理模块module bcd_modify (input       [19:0]    data_in ,//移位比较数据输入output      [19:0]    data_out //移位比较数据输出
);//信号定义wire         [3:0]      reg1    ;//移位结果输出wire         [3:0]      reg2    ;wire         [3:0]      reg3    ;//左移大4加3比较 [19:16]bcd_cmp c1(.cmp_in(data_in[19:16]),.cmp_out(reg1));//左移大4加3比较 [15:12]bcd_cmp c2(.cmp_in(data_in[15:12]),.cmp_out(reg2));//左移大4加3比较 [11:8]bcd_cmp c3(.cmp_in(data_in[11:8]),.cmp_out(reg3));//比较完成 左移一位assign data_out = {reg1[2:0],reg2,reg3,data_in[7:0],1'b0};endmodule

大四加三处理模块
在这里插入图片描述
代码实现

//大四加三处理
module bcd_cmp(input      [3:0]    cmp_in  ,//比较器数据输入output  reg[3:0]    cmp_out  //比较器数据输出
);always @(*) beginif(cmp_in > 4)cmp_out = cmp_in + 3;//大于四加三elsecmp_out = cmp_in;//小或等于四 不作处理endendmodule

3、仿真调试

仿真文件【testbench】

`timescale 1ns/1ps
module bin2bcd_tb();
reg        [7:0]     bin   ;
wire       [11:0]    bcd   ;
bin2bcd u_bin2bcd
(.bin         ( bin   ),.bcd         ( bcd   )
);
parameter CYCLE = 20;
initial begin#(CYCLE*200);bin = 8'b0;//bin信号初始化#(CYCLE*100);bin = 8'b1010_1101;//173#(CYCLE*100);bin = 8'b0000_1101;//13#(CYCLE*100);bin = 8'b1010_0100;//164#(CYCLE*100);bin = 8'b1000_0000;//128#(CYCLE*100);bin = 8'b1111_1111;//255$stop;
end
endmodule

【do】文件

vlib work
vmap work work
#编译testbench文件
vlog  bin2bcd_tb.v
#编译设计文件
vlog ../rtl/bcd_cmp.v
vlog ../rtl/bin2bcd.v
vlog ../rtl/bcd_modify.v
#指定仿真顶层
vsim -novopt work.bin2bcd_tb
#添加信号到波形窗
add wave -position insertpoint sim:/bin2bcd_tb//*

do调试流程
打开仿真调试工具modelsim
在这里插入图片描述
点击【file】->【change Directory…】
在这里插入图片描述
找到tb文件【或者仿真测试文件还有do文件所在目录】
在这里插入图片描述
左下角查看打开的目录
在这里插入图片描述
使用指令,开始仿真【do do.do】;然后回车

do filename.do

在这里插入图片描述
编译无报错【注意错误和警告信息】
在这里插入图片描述

4、仿真验证

将bin用十进制表示,加上【unsigned】
在这里插入图片描述

 #(CYCLE*200);bin = 8'b0;//bin信号初始化#(CYCLE*100);bin = 8'b1010_1101;//173#(CYCLE*100);bin = 8'b0000_1101;//13#(CYCLE*100);bin = 8'b1010_0100;//164#(CYCLE*100);bin = 8'b1000_0000;//128#(CYCLE*100);bin = 8'b1111_1111;//255

对比可以发现,输入值符合预期。
下面任意取一个值进行验证。

十进制数:128
BCD码表示:0001 0010 1000

取BCD输出的高12位为输出结果【输入为8,低位为移位补0值】
在这里插入图片描述
经过对比,输出与实际值吻合。

三、BCD码转二进制

1、原理实现

移位算法原理
二进制码左移一位等于未左移的二进制码*2,例如有二进制码101001,转成十进制等于41,左移一位得到1010010,转成十进制等于82。也就是说二进制码左移1位加上左移3位可以等效于二进制码乘以10。

2、模块划分

移位相加
在这里插入图片描述
代码实现

/************************工程说明*********************BCD码转二进制码
*****************************************************/
module bcd2bin(input                 clk      ,//系统时钟 50Mhzinput                 rst_n    ,//复位 低电平有效input        [3:0]    bw       ,//BCD码百位input        [3:0]    sw       ,//BCD码十位input        [3:0]    gw       ,//BCD码个位output       [9:0]    bin       //二进制输出
);//信号定义reg           [9:0]    bw_v1   ;//BCD码百位寄存器1reg           [9:0]    bw_v2   ;//BCD码百位寄存器2reg           [9:0]    bw_v3   ;//BCD码百位寄存器3reg           [9:0]    sw_v1   ;//BCD码十位寄存器1reg           [9:0]    sw_v2   ;//BCD码十位寄存器2reg           [9:0]    gw_v1   ;//BCD码个位寄存器/**********************换算规则:**********************BCD百位:a*100=a*(64+32+4)=a*64+a*32+a*4 =a000000+a00000+a00,即a左移6位加上左移5位加上a左移2位 BCD十位:a*10=a*(8+2)=a*8+a*2 =a000+a0,即a左移3位加上左移1位     BCD个位:个位数据不变将所有的各个位的转换结果相加就是转换后的二进制数左移运算:2^n      右移运算:1/(2^n)******************************************************///寄存器赋初值always @(posedge clk or negedge rst_n) beginif(!rst_n)beginbw_v1 <= 0;bw_v2 <= 0;bw_v3 <= 0;sw_v1 <= 0;sw_v2 <= 0;gw_v1 <= 0;endelse beginbw_v1 <= bw << 6;//左移六位bw_v2 <= bw << 5;//左移五位bw_v3 <= bw << 2;//左移两位sw_v1 <= sw << 3;//左移三位sw_v2 <= sw << 1;//左移一位gw_v1 <= gw;//个位保持不变endendassign bin = bw_v1 + bw_v2 + bw_v3 + sw_v1 + sw_v2 + gw_v1;endmodule

3、仿真验证

仿真测试文件【testbench】

//时间单位/精度
`timescale 1ns/1psmodule bcd2bin_tb();
//激励信号
reg                        clk    ;
reg                        rst_n  ;
reg            [3:0]       bw     ;
reg            [3:0]       sw     ;
reg            [3:0]       gw     ;
//输出信号
wire           [9:0]       bin    ;//模块例化
bcd2bin    u_bcd2bin
(.clk       ( clk    ),.rst_n     ( rst_n  ),.bw        ( bw     ),.gw        ( gw     ),.sw        ( sw     ),.bin       ( bin    )
);//产生时钟
parameter CYCLE = 20;always #(CYCLE/2) clk = ~clk;//产生激励initial beginclk   = 1'b0;rst_n = 1'b0;bw = 4'd0; sw = 4'd0; gw = 4'd0;//000#(CYCLE*500);rst_n = 1'b1;#(CYCLE*1000);bw = 4'd1; sw = 4'd2; gw = 4'd0;//120#(CYCLE*1000);bw = 4'd3; sw = 4'd2; gw = 4'd9;//329#(CYCLE*1000);bw = 4'd7; sw = 4'd0; gw = 4'd3;//703#(CYCLE*1000);bw = 4'd0; sw = 4'd2; gw = 4'd7;//027#(CYCLE*1000);bw = 4'd2; sw = 4'd9; gw = 4'd0;//290#(CYCLE*5000);$stop;endendmodule

do文件

vlib work
vmap work work#编译testbench文件
vlog bcd2bin_tb.v#编译设计文件 
vlog ../rtl/bcd2bin.v#指定仿真顶层
vsim -novopt work.bcd2bin_tb#添加信号到波形窗
add wave -position insertpoint sim:/bcd2bin_tb//*

验证结果
输入值查看
在这里插入图片描述
仿真输入值

bw = 4'd0; sw = 4'd0; gw = 4'd0;//000#(CYCLE*500);rst_n = 1'b1;#(CYCLE*1000);bw = 4'd1; sw = 4'd2; gw = 4'd0;//120#(CYCLE*1000);bw = 4'd3; sw = 4'd2; gw = 4'd9;//329#(CYCLE*1000);bw = 4'd7; sw = 4'd0; gw = 4'd3;//703#(CYCLE*1000);bw = 4'd0; sw = 4'd2; gw = 4'd7;//027#(CYCLE*1000);bw = 4'd2; sw = 4'd9; gw = 4'd0;//290#(CYCLE*5000);

输出结果

百位:左移六位+左移五位+左移两位
十位:左移三位+左移一位
个位:不变

在这里插入图片描述
经对比,结果符合预期。


http://chatgpt.dhexx.cn/article/VoEQrxgO.shtml

相关文章

BCD格式及与十进制/十六进制的转换

本文框架 前言1. BCD码是什么&#xff1f;2. 不同进制与BCD码之间的转换2.1 十进制与BCD码的转换2.1.1 十进制转换为BCD码2.1.2 BCD码转换为十进制 2.2 十六进制与BCD码的转换 前言 本系列Autosar 诊断入门介绍&#xff0c;会详细介绍诊断相关基础知识&#xff0c;如您对诊断实…

BCD码详解

BCD码的种类 BCD码可分为有权码和无权码两类&#xff1a;有权BCD码有8421码、2421码、5421码&#xff0c;其中8421码是最常用的&#xff1b;无权BCD码有余3码、格雷码等。 8421 BCD码 8421 BCD码是最基本和最常用的BCD码&#xff0c;它和四位自然二进制码相似&#xff0c;各位…

二进制码转BCD码

在单片机里面&#xff0c;如&#xff1a;显示个温度值&#xff0c;这时&#xff0c;要取一个数的个位、十位、百位&#xff0c;可以用/和 %&#xff08;求商和求余&#xff09;来解决。 但是&#xff0c;在FPGA里面用求商和求余将会非常消耗资源&#xff0c;这样就必须用到二进…

【C语言】BCD码、十进制互相转换

目录 0. 前言&#xff1a; 1. BCD码 2. 算法原理 3. 进制转换 3.1 两位BCD码的转换&#xff1a; 3.2 其他进制转换 3.3 任意进制转二进制 参考资料&#xff1a; 0. 前言&#xff1a; 记录今天用15单片机写DS1302时钟芯片程序的时候遇到的问题 时间显示是这个样的 0 1…

什么是 BCD(二进制编码的十进制)

BCD 是一位十进制数&#xff0c;由代表 0 到 9 的四位二进制数字表示。 当寄存器值以十六进制表示时&#xff0c;可以原样读取为十进制数&#xff0c;这对于处理十进制数的函数来说非常方便。 二进制数的 4 位可以表示为 0 到 15&#xff0c;但只有低 10 位被视为有效数字。 …

十进制转8421_BCD码

目录 一、BCD码简介 二、十进制转8421BCD码转换思路 三、程序编写 四、仿真验证 总结 一、BCD码简介 BCD码&#xff08;Binary-Coded Decimal‎&#xff09;&#xff0c;用4位二进制数来表示1位十进制数中的0~9这10个数码&#xff0c;是一种二进制的数字编码形式&#xff0c;常…

十进制数转换BCD码

有必要仔细阐述这一节&#xff0c;目前就是用在数码管显示&#xff0c;在单片机使用时&#xff0c;我们通常是将十进制数字进行/和%运算&#xff0c;得到每个位置的十进制数字&#xff0c;在这里可能是为了节省使用存储器的量&#xff0c;运用的是加三移位法具体其实就是将每个…

C语言:十进制、BCD码互换

目录 1、复杂版 2、简易版 最近写单片机 RTC 日期、时间配置&#xff0c;需要实现十进制、BCD码互换&#xff0c;将示例Demo分享给各位朋友&#xff1a; BCD是指用二进制来表示十进制数的编码&#xff0c;即&#xff1a;用4位二进制来表示一位十进制数&#xff0c;因此4位二进…

BCD码转化为十进制数

2019独角兽企业重金招聘Python工程师标准>>> 什么是BCD码&#xff1a;用4位二进制数来标识十进制数中的0-9这十个数的编码形式&#xff0c;简称为BCD码。BCD码优点&#xff1a;这种编码形式使二进制和十进制之间的转换能够快捷进行。采用BCD码&#xff0c;既可保存数…

BCD码以及各进制之间的相互转换

目录 前言 一、BCD码 二、进制互转 1、任意进制转十进制&#xff1a;系数X基数 ^ 权值&#xff08;累加&#xff09; 2、任意进制转二进制 前言 主要学习什么是BCD码&#xff0c;以及二进制、八进制、十进制、十六进制之间的相互转换 一、BCD码 BCD码就是以四位二进制数为一…

BCD码与十进制数间转换

一、前言&#xff1a; 这几天在项目协议对接的时候有一部分功能是获取系统时间功能与校时功能。小马哥获取到时间后打印了一下 2020-5-26 20:06:32&#xff0c;一看时间是对的&#xff0c;然后美滋滋的组装协议发送平台测试了。测试的时候发现月、日、时分秒数据都正常&#x…

黑马Python笔记3

输入时&#xff0c;占位符在引号里面&#xff0c;而要接受的变量在引号外面eg:"…%d"%player) expected an indented block&#xff1a;缩进错误。if对缩进有要求&#xff0c;python对缩进要求严格 if表判断 双等号一定要记住&#xff01;&#xff01;&#xff01; i…

2021-03-30 黑马Python学习笔记

操作系统OS&#xff08;Operation System&#xff09; 操作系统作用 1、直接操作硬件 2、把操作硬件的代码封装成系统调用&#xff0c;供其他成员间接操作硬件 没有安装操作系统的计算机被称为裸机 如果想在裸机上运行程序&#xff0c;必须用机器语言书写程序 如果计算机上…

黑马python在线培训

过去的2017年这一年&#xff0c;Python 开发者在全球快速增长&#xff0c;国内小伙伴学习 Python 的热情一路高涨。同时&#xff0c;Python 成为大量开发者推荐的入门编程语言和第二编程语言。2017年12月&#xff0c;Python 在 TIOBE 全球编程语言年度排行榜上升至第四&#xf…

黑马python培训安排

在分享资源之前&#xff0c;大家可以先想清楚未来的职业发展方向。毕竟只有找到未来职业发展方向&#xff0c;才更清楚当下重点学习的内容。 根据上图我们基本上一目了然&#xff0c;找到自己未来要发展的方向。在找到之后可以在各个招聘app上了解一下相关岗位的技能要求是什么…

[学习笔记]黑马程序员python教程

文章目录 思维导图Python基础知识图谱面向对象SQL入门和实战Python高阶技巧 第一阶段第九章&#xff1a;Python异常、模块与包1.9.1异常的捕获1.9.1.1 为什么要捕获异常1.9.1.2 捕获常规的异常1.9.1.3 捕获指定的异常1.9.1.4 捕获多个异常1.9.1.5 捕获全部异常1.9.1.6 异常的el…

黑马python6.0培训视频

关于对Python有一些了解的同学&#xff0c;肯定都会说Python语法简洁适合新手&#xff0c;便于阅读等这些方面。实际上是这样的&#xff0c;很多国内计算机专业都是C语言作为第一门学习的语言&#xff0c;很多国外的却是Python入门。因为Python可以让你在短时间内找到成就感&am…

黑马 Python 数据结构与算法第一章

背景知识 1.数组是一种线性表结构&#xff0c;其用一块连续的内存空间&#xff0c;来存储一组具有相同类型的数据&#xff1b; 2.时间复杂度&#xff0c;也叫做渐进时间复杂度&#xff0c;通常用大O公式书写&#xff0c;表示代码的执行时间随数据规模增长的变化趋势&#xff0c…

黑马程序员 python 数据分析 代码_2020年最新版 5.0程序员 黑马python人工智能数据分析机器学习软件测试全栈开发...

阶段一: 5.0课程资料 收起 第一章: 1-Python基础语法v5.0 第二章: 2-面向对象编程v5.0 第三章: 3-linux命令v5.0 第四章: 4-多任务编程v5.0 第五章: 5-web服务器v5.0 第六章: 6-web前端开发基础v5.0 第七章: 7-MySQL数据库v5.0 第八章: 8-mini-web框架v5.0 第九章: 9-django框架…

黑马python培训视频网盘下载

前几天看到朋友老周发了个朋友圈&#xff0c;我心态立马炸了&#xff1a; 好家伙&#xff01;竟然有钱入手五位数的最新款手机&#xff0c;这也太酸了吧&#xff01; 可他不是整天哭穷么&#xff0c;哪来这么多钱&#xff1f;我的内心充满了疑惑。 趁着昨天他来我家&#xff0c…