基于FPGA的二进制转BCD
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的更多相关文章
- FPGA中将十进制数在数码管中显示(verilog版)--二进制转换为BCD码
这周有朋友问怎样在fpga中用数码管来显示一个十进制数,比如1000.每个数码管上显示一位十进制数.如果用高级语言来分离各位,只需要分别对该数做1000,100,10对应的取商和取余即可分离出千百十个 ...
- FPGA加三移位算法:硬件逻辑实现二进制转BCD码
本文设计方式采用明德扬至简设计法.利用FPGA来完成显示功能不是个很理想的方式,当显示任务比较复杂,要通过各种算法显示波形或者特定图形时,当然要用单片机通过C语言完成这类流程控制复杂,又对时序要求不高 ...
- 基于Verilog HDL的二进制转BCD码实现
在项目设计中,经常需要显示一些数值,比如温湿度,时间等等.在数字电路中数据都是用二进制的形式存储,要想显示就需要进行转换,对于一个两位的数值,对10取除可以得到其十位的数值,对10取余可以得到个位的数 ...
- 基于FPGA的简易数字时钟
基于FPGA的可显示数字时钟,设计思路为自底向上,包含三个子模块:时钟模块,进制转换模块.led显示模块.所用到的FPGA晶振频率为50Mhz,首先利用它得到1hz的时钟然后然后得到时钟模块.把时钟模 ...
- 基于FPGA的线阵CCD图像测量系统研究——笔记
本文是对基于FPGA的线阵CCD图像测量系统研究(作者:高尚)的阅读笔记 第一章绪论 1. 读读看 读了前面的摘要依然没有看懂作者要做什么.接着往下读....终于看到了一个字眼“基于机器视觉的图像测量 ...
- 基于FPGA的红外遥控解码与PC串口通信
基于FPGA的红外遥控解码与PC串口通信 zouxy09@qq.com http://blog.csdn.net/zouxy09 这是我的<电子设计EDA>的课程设计作业(呵呵,这个月都拿 ...
- 基于FPGA的数字秒表(数码管显示模块和按键消抖)实现
本文主要是学习按键消抖和数码管动态显示,秒表显示什么的,个人认为,拿FPGA做秒表真是嫌钱多. 感谢 感谢学校和至芯科技,笔者专业最近去北京至芯科技培训交流了一周.老师的经验还是可以的,优化了自己的代 ...
- 基于FPGA的飞机的小游戏
基于FPGA的飞机的小游戏 实验原理 该实验主要分为4个模块,采用至上而下的设计方法进行设计.由50M的晶振电路提供时钟源,VGA显示控制模块.图形显示控制模块.移动模块的时钟为25M,由时钟分频电路 ...
- 【代码】二进制转BCD [转]
BCD:Binary Coded Decimal 即用4位二进制编码表示1位的十进制数. 定义:BCD码这种编码形式利用了四个位元来储存一个十进制的数码,使二进制和十进制之间的转换得以快捷的进行. ...
- 基于FPGA的音频信号的FIR滤波(Matlab+Modelsim验证)
1 设计内容 本设计是基于FPGA的音频信号FIR低通滤波,根据要求,采用Matlab对WAV音频文件进行读取和添加噪声信号.FFT分析.FIR滤波处理,并分析滤波的效果.通过Matlab的分析验证滤 ...
随机推荐
- Eagle+欧奥PicHome创建私有的pinterest网站
Pinterest和花瓣网, 是设计师寻找灵感的天堂!它能够帮你采集.存储和发现灵感.可以说是设计师必用的网站. Eagle是设计师个人的灵感收集工具,它能够方便的采集素材,并快速为图片标签,分类,评 ...
- GridSearch 最佳 estimator 设置问题
GridSearchCV 最佳 estimator 设置问题 def train_model_Grid(estimator, param_grid, cv, X_train, X_test, y_tr ...
- linux安装/切换不同版本c/c++
查看ubuntu系统上g++的版本: ls /usr/bin/g++* 安装指定版本gcc和g++ # 以version == 4.9为例 sudo apt-get install gcc-4.9 g ...
- #回滚莫队#AT1219 歴史の研究
洛谷题目 AT1219 分析 不满足区间减性质的运算,如最值,就不能用普通莫队求, 考虑回滚莫队,它的核心思想就是若区间在块内直接暴力, 否则将右端点从小到大排序,右端点按普通莫队求,那么左端点由于只 ...
- 常用的Numpy通用函数列表
官网来源:Universal functions (ufunc) - NumPy v1.21 Manual 数学运算(Math operations) 表达式 定义 add(x1, x2, /[, o ...
- 【FAQ】接入HMS Core广告服务中的常见问题总结和解决方法
HMS Core广告服务(Ads Kit)为开发者提供流量变现服务和广告标识服务,依托华为终端能力,整合资源,帮助开发者获取高质量的广告内容.同时提供转化跟踪参数服务,支持三方监测平台.广告主进行转化 ...
- Linux程序崩溃自启动方法
linux进程挂掉后,可以通过配置 systemd 来自动启动服务 1.创建 systemd 服务文件,例如:huyang.service,需要放置在系统文件夹 /etc/systemd/system ...
- std::thread 六:多线程&单例类
为了避免单例类在多线程中重复的创建,下面提供了两种解决方法: 1.互斥锁+双重检查 2.std::call_once() 方法一:互斥锁+双重检查 #include <iostream> ...
- 14款DevOps/SRE工具,助力提升运维效率
简介 随着平台工程的兴起,DevOps 和 SRE 不断发展,带来了新一代工具,旨在提高软件开发和运维的效率.可扩展性和可靠性. 在本篇文章中,我们将深入探讨一些最具发展前景的工具,它们正在塑造持续集 ...
- Scratch3之AI集成 - flappy bird AI版本
AI神秘且有趣,我们一个经典的游戏flappy bird集成AI,实现自训练成长的聪明的笨鸟.先上效果: 初始化的笨鸟拥有分身,每个分身都有自我学习功能,根据自己的移动轨迹和得分情况进行汇总,进行新一 ...