BCD码(nary-Coded Decimal‎)又称二-十进制代码,亦称二进码十进数。是一种二进制的数字编码形式,用二进制编码的十进制代码。这种编码形式利用了四个位元来储存一个十进制的数码。

在数字电路中,没有特殊说明的数码都是顺序编码的二进制。转换为BCD码,也就是将顺序编码的二进制数字的个位、十位、百位等计算出来,用四位二进制表示,组合到一起就是BCD码。

将一个数字对10求余将得到个位。

将一个数字减去个位后,除以10,然后在对10求余将得到十位。由于在FPGA内部,正数除法不会保留小数,所以可以直接除以10,而不用减去个位。

将一个数字除以100,然后对10求余得到百位。

首先设计一个8位的二进制转成BCD码。8位的二进制能够表示最大的数字为255,共有三个BCD码,输出共有12位。

此模块命名为bin2bcd,bin为二进制输入,bcd为BCD码输出。

设计代码如下:

module bin2bcd (

input   wire    [7:0]     bin,

output  wire    [11:0]    bcd

);

assign bcd[3:0] = bin%10;

assign bcd[7:4] = (bin/10)%10;

assign bcd[11:8] = (bin/100)%10;

endmodule

在testbench中,可以利用随机数给出几个数值。

`timescale 1ns/1ps

module bin2bcd_tb;

reg     [7:0]     bin;

wire    [11:0]    bcd;

bin2bcd bin2bcd_inst(

.bin        (bin),

.bcd        (bcd)

);

initial begin

repeat (10) begin

bin = {$random} % 256;

# 20;

end

end

endmodule

在modelsim中,将bin设置为符号位,将bcd设置为十六进制。十六进制也是4个二进制码组成一个,只不过BCD码中只有0到9,而十六进制中还有A到F。

通过RTL仿真图可以看出,bin和bcd的数字是相同的。

在此设计代码中只有三行,但是涉及到了除法器和求余器(也可以认为是除法器),利用了较多的资源。

为了减少资源使用,使得延迟更小,二进制转BCD还有其他的办法。

首先分析两个BCD数码的相加。

0101  0010

+    0010  0110

0111  1000

在上述BCD码加法中,52+26最终结果等于78,结果没有任何错误。

0101  1001

+   0010  0010

0111  1011

在上述BCD码加法中,59+22最终结果等于7B,很明显出现了不属于BCD码中的数字。BCD码是用来表示十进制数字的,顺序编码时表示二进制的,当四个组到一起时,变为十六进制,当BCD码算完的结果中有大于9的数码,可以进行加六调整。加上六后,就会得到正确的进位和本位值。

当结果为1011(B)时,加上0110(6),本位结果为0001,进位为0001。

0111 1011(7B)调整后,为1000 0001(81),结果正确。

上面是分析的是两个不同的BCD码相加,下面分析两个相同的BCD码相加(最终结果不用调整时),相同的两个数字相加,可以用左移表示。

0010   0011

+    0010   0011

0100   0110

两个相同的BCD码相加(最终结果需要调整时),就需要加六调整了。

0010   0111

+    0010   0111

0100   1110

上述结果就需要加六调整了,因为最终结果中出现了比9大的数字。因为是两个相同的数字相加,当数字大于4后,两个相同的数字相加就会大于9,此时就需要加6调整。

当数字大于4,先加上3,此时把两个相同的结果进行相加,就实现了加之后的结果大于9,然后再加六。这两种方法是一样的。

当数字大于4,先加上3,然后进行移位。和先加,判断结果是不是大于9,然后再加6是相等的。

由于是相等的两个数字相加,末位肯定为0 。那么两个相同的BCD相加,再和一个1bit的数字相加,就可以认为是当数字大于4,先加上3,然后进行移位,把最后移位出来的0直接换成最后加的1bit数字即可,将上述操作定义为操作X。

当了解了上述结论后,下面分析,利用上述结论实现二进制转BCD。

任何一个二进制码都可以写成本位的数字乘以本位的权重的累加和。

将一个7位的二进制数据转为BCD,首先认为是两个都为0的bcd码相加,然后加上7位数据的最高位。

上述的结果就是最高位转换为BCD码的结果,它的权重应该是2的6次幂,但是现在是2的0次幂。

然后将上述的结果和数据的次高位进行操作X,那么此时数据的最高位的权重变为2的1次幂,次高位的权重变为2的0次幂,结果为最高位和次高位的BCD码。

依次类推,将八位数据全部进行操作X后,各个数据位都是自己的权重,并且结果就是BCD码。

在操作X中,为了方便将1bit的数据去替换结果的最后一位,可以将1bit放在调整好的数据的后面,直接移位进去即可。

在图中,经历了7 次的操作X。如果我们可以把操作X设计出来,然后级联7个即可得到正确结果。

操作X的输入为前面的BCD码和后面的二进制(可以将这两组合到一起)。

操作X为调整和移位,后面用调整和移位来表示。

为了能够对比两种二进制转BCD(除法求余和调整移位),下面利用调整和移位的方法实现8位二进制转BCD。

输入是八位,就需要进行八次的调整和移位。由于每次调整和移位的操作是完全相同的,所以将调整和移位做成一个模块。

该模块命名为adjust_shift,输入为BCD码的位数加上二进制的位数等于20位,输出也是20位。

module adjust_shift (

input       wire        [19:0]      idata,

output         wire  [19:0]      odata

);

wire                  [19:0]      adjust_data;

assign adjust_data[19:16] = idata[19:16] > 4'd4 ? idata[19:16] + 4'd3 : idata[19:16];

assign adjust_data[15:12] = idata[15:12] > 4'd4 ? idata[15:12] + 4'd3 : idata[15:12];

assign adjust_data[11:8] = idata[11:8] > 4'd4 ? idata[11:8] + 4'd3 : idata[11:8];

assign adjust_data[7:0] = idata[7:0];

assign odata = adjust_data << 1'b1;

endmodule

当调整移位设计做完之后,我们只需要级联八个就可以得到结果。第一个输入时,高位(BCD)要输入为0;最后一个输出时,高位(BCD)才是输出。

module bintobcd (

input       wire                  [7:0]       bin,

output       wire                 [11:0] bcd

);

wire             [19:0] adjust_shift_data_0;

wire             [19:0] adjust_shift_data_1;

wire             [19:0] adjust_shift_data_2;

wire             [19:0] adjust_shift_data_3;

wire             [19:0] adjust_shift_data_4;

wire             [19:0] adjust_shift_data_5;

wire             [19:0] adjust_shift_data_6;

wire             [19:0] adjust_shift_data_7;

adjust_shift  adjust_shift_inst0 (.idata({12’d0,bin}),.odata(adjust_shift_data_0));

adjust_shift  adjust_shift_inst1 (.idata(adjust_shift_data_0),.odata(adjust_shift_data_1));

adjust_shift  adjust_shift_inst2 (.idata(adjust_shift_data_1),.odata(adjust_shift_data_2));

adjust_shift  adjust_shift_inst3 (.idata(adjust_shift_data_2),.odata(adjust_shift_data_3));

adjust_shift  adjust_shift_inst4 (.idata(adjust_shift_data_3),.odata(adjust_shift_data_4));

adjust_shift  adjust_shift_inst5 (.idata(adjust_shift_data_4),.odata(adjust_shift_data_5));

adjust_shift  adjust_shift_inst6 (.idata(adjust_shift_data_5),.odata(adjust_shift_data_6));

adjust_shift  adjust_shift_inst7 (.idata(adjust_shift_data_6),.odata(adjust_shift_data_7));

assign bcd = adjust_shift_data_7[19:8];

endmodule

第一级输入时,采用位拼接的方式。

编写testbench后,经过RTL仿真验证,结果都是正确的。 在达到相同功能的前提下,调整和移位的方式实现的设计,资源利用如下:

在达到相同的功能下,一个是164,一个是29,对比结果很明显。

设计者:郝旭帅         QQ:746833924     QQ交流群: 173560979

基于FPGA的二进制转BCD的更多相关文章

  1. FPGA中将十进制数在数码管中显示(verilog版)--二进制转换为BCD码

    这周有朋友问怎样在fpga中用数码管来显示一个十进制数,比如1000.每个数码管上显示一位十进制数.如果用高级语言来分离各位,只需要分别对该数做1000,100,10对应的取商和取余即可分离出千百十个 ...

  2. FPGA加三移位算法:硬件逻辑实现二进制转BCD码

    本文设计方式采用明德扬至简设计法.利用FPGA来完成显示功能不是个很理想的方式,当显示任务比较复杂,要通过各种算法显示波形或者特定图形时,当然要用单片机通过C语言完成这类流程控制复杂,又对时序要求不高 ...

  3. 基于Verilog HDL的二进制转BCD码实现

    在项目设计中,经常需要显示一些数值,比如温湿度,时间等等.在数字电路中数据都是用二进制的形式存储,要想显示就需要进行转换,对于一个两位的数值,对10取除可以得到其十位的数值,对10取余可以得到个位的数 ...

  4. 基于FPGA的简易数字时钟

    基于FPGA的可显示数字时钟,设计思路为自底向上,包含三个子模块:时钟模块,进制转换模块.led显示模块.所用到的FPGA晶振频率为50Mhz,首先利用它得到1hz的时钟然后然后得到时钟模块.把时钟模 ...

  5. 基于FPGA的线阵CCD图像测量系统研究——笔记

    本文是对基于FPGA的线阵CCD图像测量系统研究(作者:高尚)的阅读笔记 第一章绪论 1. 读读看 读了前面的摘要依然没有看懂作者要做什么.接着往下读....终于看到了一个字眼“基于机器视觉的图像测量 ...

  6. 基于FPGA的红外遥控解码与PC串口通信

    基于FPGA的红外遥控解码与PC串口通信 zouxy09@qq.com http://blog.csdn.net/zouxy09 这是我的<电子设计EDA>的课程设计作业(呵呵,这个月都拿 ...

  7. 基于FPGA的数字秒表(数码管显示模块和按键消抖)实现

    本文主要是学习按键消抖和数码管动态显示,秒表显示什么的,个人认为,拿FPGA做秒表真是嫌钱多. 感谢 感谢学校和至芯科技,笔者专业最近去北京至芯科技培训交流了一周.老师的经验还是可以的,优化了自己的代 ...

  8. 基于FPGA的飞机的小游戏

    基于FPGA的飞机的小游戏 实验原理 该实验主要分为4个模块,采用至上而下的设计方法进行设计.由50M的晶振电路提供时钟源,VGA显示控制模块.图形显示控制模块.移动模块的时钟为25M,由时钟分频电路 ...

  9. 【代码】二进制转BCD [转]

    BCD:Binary Coded Decimal 即用4位二进制编码表示1位的十进制数.   定义:BCD码这种编码形式利用了四个位元来储存一个十进制的数码,使二进制和十进制之间的转换得以快捷的进行. ...

  10. 基于FPGA的音频信号的FIR滤波(Matlab+Modelsim验证)

    1 设计内容 本设计是基于FPGA的音频信号FIR低通滤波,根据要求,采用Matlab对WAV音频文件进行读取和添加噪声信号.FFT分析.FIR滤波处理,并分析滤波的效果.通过Matlab的分析验证滤 ...

随机推荐

  1. Web Audio API 第2章 完美的播放时机控制

    Web Audio API 第2章 完美的播放时机控制 相较于 标签, Web Audio API 拥有低延迟精确定时模型. 低延时对于游戏或交互式应用来说非常重要,因为交互操作时要快速响应给用户的听 ...

  2. centos7上单机安装fastdfs6.0.9

    目录 1.背景 2.fastdfs的一些知识 2.1 fastdfs的特点 2.2 架构图 2.2.1 client 介绍 2.2.2 tracker-server 介绍 2.2.3 storage- ...

  3. 没有Python基础,如何学习用Python写机器学习

    前言 我是一个完全没用过python的人,所以,想写机器学习,就得从语法入手. 首先上W3cSchool去学习基础语法. 基础语法都差不多,重点看一下函数,模块,面向对象. 函数的写法稍有不同,格式上 ...

  4. KafkaConsumerDemo

    pom <dependency> <groupId>org.springframework.kafka</groupId> <artifactId>sp ...

  5. KingbaseES V8R3集群运维案例之---流复制异步同步及全同步模式配置

    案例说明: 通过案例描述KingbaseES V8R3集群异步.同步及全同步强一致性配置,本案例为一主二备的架构. 适用版本: KingbaseES V8R3 集群架构: 集群复制配置参数说明: 1) ...

  6. KingbaseES 数据库安装报错案例分析

    Linux系统安装V008R006C007B0012版本KingbaseES数据库报错:Unsupported major.minor version 52.0 系统版本: [root@vm-10-3 ...

  7. #线段树,组合计数,二项式定理#CF266E More Queries to Array

    洛谷传送门 CF266E传送门 分析 首先区间修改区间查询首选线段树 要找突破口,\((i-l+1)^k\)中\(i\)不是定值, 显然得拆开,而且\(k\)很小,根据二项式定理, \[\sum_{i ...

  8. #网络流,最小割#洛谷 1344 [USACO4.4]追查坏牛奶Pollutant Control

    题目 分析 考虑答案求的是最小割,但是最小割的最小边数有点难求, 考虑建立双关键字,其实就是将边权赋值为原边权\(*mx+1\), 其中\(mx\)是一个比较大的数,不需要太大, 这样用网络流做之后对 ...

  9. JDK9的新特性:String压缩和字符编码

    目录 简介 底层实现 总结 简介 String的底层存储是什么?相信大部分人都会说是数组.如果要是再问一句,那么是以什么数组来存储呢?相信不同的人有不同的答案. 在JDK9之前,String的底层存储 ...

  10. Ubuntu部署Django三:编写相关配置文件及启动服务

    1. uwsgi 1.1 项目结构如下,你要知道 uwsgi.ini 放在什么位置 projectName |-- app |-- projectName |-- -- wsgi.py |-- -- ...