这周有朋友问怎样在fpga中用数码管来显示一个十进制数,比如1000。每个数码管上显示一位十进制数。如果用高级语言来分离各位,只需要分别对该数做1000,100,10对应的取商和取余即可分离出千百十个位。但是FPGA做除法非常耗资源。有没有其它解决办法?因为用verilog写程序时虽然形式上可以写为比如256,但是实际存储对应的还是0100H,且一个数码管只能显示一个十进制数。因此这个问题相当于二进制如何转换为一个BCD(Binary Code Decimal)码数。

本文只考虑最常见的8421码的转换,而且是压缩BCD码。

一、算法原理

根据二进制与十进制转换的定义可知,将二进制数按位加权求和即可得到。用公式描述为n位二进制转换10进制公式

A(n-1)*2^(n-1)+A(n-2)*2^(n-2)+........+A(0)*2^0=对应十进制数    (1)

将公式(1)一直提取公因子2,可很容易将公式(1)转换为公式(2),如下所示:

(A(n-1)*2+A(n-2))*2+A(n-3))*2........+a(0) =对应十进制数          (2)

即对于n位二进制数的按权展开求和,由最高的2的n-1次幂,转换为乘以n-1次2,以此类推n-2次幂,n-3次幂……。因为左移一位相当于乘以2,这样乘法操作就转换为了左移操作。

1、BCD码有0~9共计10个数码,用四位二进制表示0000~1001即可表示,而四位二进制可以表示数的范围为0000~1001~1111,即0~9~15。总计多处了 6个数码A~F。我们知道十进制逢十进一,十六进制逢十六进一。从而产生了一个非常关键的问题,转换到大于等于10以后的数字后本应由低位向紧邻的高位进位,但是只能到大于16以后进位。如DH(12D)十进制本应进位产生十位1,和个位2,但是却变成十六进制的DH。所以必须进行修正,修正的方法是加6。

2、BCD码是二进制编码的十进制,逢十进一,10/2=5.因此得到判断条件,即判断每四位是否大于4,因为5-9进一位(左移)溢出。

3、对于左移操作,相当于每进一位就会丢掉6,那么就要加上6/2=3(3左移一位后相当于6)。每次调整在左移之前完成。

*因此二进制转BCD的方法是通过左移,然后每四位判断是否大于4,满足则加3.

二、基于Verilog的代码实现

为了简便,本代码是以十进制数1000为例进行测试。1000D = 3E8H = 0011 1110 1000B。

 /*******************************************************************
* 功能:将二进制数转换为BCD码数,在七段数码管上显示
* 原理:左移 + 3
* 作者:国静德远
* 时间:2017年4月16日
*******************************************************************/
module BinaryToBCD(CLOCK_50, HEX3, HEX2, HEX1, HEX0); input CLOCK_50;
output [:] HEX3, HEX2, HEX1, HEX0; wire [:] TestData;
wire [:] ResultData;
assign TestData = 'd1001;
//Binary to BCD
Binary2BCD ConvertData(CLOCK_50, TestData, ResultData);
//Display
Seg7 H1(ResultData[ : ], HEX0);
Seg7 H2(ResultData[ : ], HEX1);
Seg7 H3(ResultData[ : ], HEX2);
Seg7 H4(ResultData[ : ], HEX3); endmodule //Convert Data by left + 3
module Binary2BCD(inClk, inData, outData);
input inClk;
input [:] inData;
output [:]outData; reg [:]count10 = ;
reg [:]ShiftReg; always@(posedge inClk)
begin
if(count10 >= && count10 <= )
begin
count10 <= count10 - 'b1;
end
else
count10 <= 'd15;
end always @(posedge inClk)
begin
//for(i = 9; i >= 0; i = i - 1)
if(count10 >= && count10 <= )
begin
// shift left
ShiftReg = (ShiftReg << );
ShiftReg[] = inData[count10];
//adjust by add 3
if(ShiftReg[:] > )
ShiftReg[:] = ShiftReg[:] + 'd3;
else
ShiftReg[:] = ShiftReg[:]; if(ShiftReg[:] > )
ShiftReg[:] = ShiftReg[:] + 'd3;
else
ShiftReg[:] = ShiftReg[:]; if(ShiftReg[:] > )
ShiftReg[:] = ShiftReg[:] + 'd3;
else
ShiftReg[:] = ShiftReg[:]; if(ShiftReg[:] > )
ShiftReg[:] = ShiftReg[:] + 'd3;
else
ShiftReg[:] = ShiftReg[:]; end
else
ShiftReg = ShiftReg;
end assign outData = ShiftReg; endmodule //Display on 7seg
module Seg7(inData, outData);
input [:]inData;
output [:]outData;
//reg [3:0]inData;
reg [:]outData;
always@(inData)
begin
case(inData)
'd0: outData = 8'b1100_0000;
'd1: outData = 8'b1111_1001;
'd2: outData = 8'b1010_0100;
'd3: outData = 8'b1011_0000;
'd4: outData = 8'b1001_1001;
'd5: outData = 8'b1001_0010;
'd6: outData = 8'b1000_0010;
'd7: outData = 8'b1111_1000;
'd8: outData = 8'b1000_0000;
'd9: outData = 8'b1001_0000;
default: outData = 'b1111_1111;
endcase
end
endmodule

仿真结果如下图所示:

FPGA中将十进制数在数码管中显示(verilog版)--二进制转换为BCD码的更多相关文章

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

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

  2. Delphi中对BCD码的直接支持 (转)

    最近在Delphi下写软件,需要将数据转换为BCD码和将BCD码转换为其它数据类型,从网上搜索了一下,没有发现好的函数,于是就想自定义函数来完成BCD与其它格式的数据转换功能.但最终没有动手写,先查查 ...

  3. PHP中将ip地址转成十进制数的两种实用方法

    As we all know that long2ip works as ip1.ip2.ip3.ip4 (123.131.231.212) long ip => (ip1 * 256 * 25 ...

  4. Java中实现十进制数转换为二进制的三种思路

    Java中实现十进制数转换为二进制 第一种:除基倒取余法 这是最符合我们平时的数学逻辑思维的,即输入一个十进制数n,每次用n除以2,把余数记下来,再用商去除以2...依次循环,直到商为0结束,把余数倒 ...

  5. 在Java中,为什么十六进制数0xFF取反之后对应的十进制数是-256呢?

    int number = 0xFF: 字面值是指在程序中无需变量保存,可直接表示为一个具体的数字或字符串的值. 0xFF是一个整数字面值,整数字面值的缺省类型是 int. 我们知道在Java中, in ...

  6. Java中实现十进制数转换为二进制的三种方法

    第一种:除基倒取余法 这是最符合我们平时的数学逻辑思维的,即输入一个十进制数n,每次用n除以2,把余数记下来,再用商去除以2...依次循环,直到商为0结束,把余数倒着依次排列,就构成了转换后的二进制数 ...

  7. verilog实验1:基于FPGA蜂鸣器演奏乐曲并数码管显示

    一.实验任务 利用FPGA进行代码开发,使蜂鸣器演奏出乐曲<生日快乐>,将音调显示在数码管.原理为蜂鸣器为交流源蜂鸣器,在引脚上加一定频率的方波就可以发声,而且发声的频率由所加方波决定.这 ...

  8. 将十进制数转为一个n位数的密码(每位都是个m进制数)

    例如一个6位数的10进制密码,共有106个密码,如果把每个6位数的密码编成号就是[0,106-1].这是十进制的情况,即6个位,每个位有10种选择.如果要遍历所有密码,需要6重for循环,每个循环10 ...

  9. 实验10.3_数值显示拓展_dword型数转变为表示十进制数的字符串

    assume cs:code data segment db 10 dup (0) data ends code segment start : mov ax,4240H;F4240H=1000000 ...

随机推荐

  1. JS排序算法

    1.冒泡排序 冒泡算法是比较相邻的两项,如果前者比后者大,就交换他们. 假设一共有n项,那么一共需要n-1趟,第一趟需要交换n-1次,但是第一趟结束后,最后一项基本确定就是最大项了,所以第二次需要交换 ...

  2. 为什么Node.JS会受到青睐?

    为什么会是Node.JS? 从技术上讲,Node.JS不是一个非常好的项目,Node.JS只是把一个烂想法实现到了可以接受的程度. 但是人们为什么愿意用Node.JS? 从历史看来,成功的项目从来都不 ...

  3. 轻松理解JavaScript闭包

    摘要 闭包机制是JavaScript的重点和难点,本文希望能帮助大家轻松的学习闭包 一.什么是闭包? 闭包就是可以访问另一个函数作用域中变量的函数. 下面列举出常见的闭包实现方式,以例子讲解闭包概念 ...

  4. 2017年最新chrome必备插件推荐

    1. 上网必备 Speed dial plus新标签页, 直接替换掉chrome自带的毫无新意的新标签页,简洁优美快速,我本人非常喜欢. &amp;lt;img src="https ...

  5. Android -- 自定义ScrollView实现放大回弹效果

    1,刚刚在别人开源的项目中看到了一个挺不错的用户体验,效果图如下: 2,那下面我们就来实现一下,首先看一下布局,由于一般只是我们包含头像的那部分方法,所以这里我们要把布局分成两部分,对应的布局文件效果 ...

  6. iOS最好用的弹出框

    重构项目时发现有的时候需要弹出提示,比如登录成功,数据请求失败,还有选择相机或者相册来上传头像等等. 今天就自己写了一个弹出框,采用的是系统的UIAlertController,只不过自己有定义了一些 ...

  7. ASP.NET MVC创建视图过程

    MvcHandler.ProcessRequest()   (1)获取Action执行结果:context2.Result ActionExecutedContext context2 = this. ...

  8. 用ListView实现对数据库的内容显示

    用ListView实现对数据库的内容显示 创建一个触发机制 ---------(作用)将数据读入ArrayList集合中 MyBase base = new MyBase(); SQLiteDatab ...

  9. iOS全角符与半角符之间的转换

    iOS全角符与半角符之间的转换 相关资料: 函数『CFString​Transform』中文 详情: 问题 1.17-03-15,「有人在群里边问怎么把『半角』符字符串转换成『全角』字符串?」,百度的 ...

  10. Scut游戏引擎改造兼容Codis。

    原生的Scut引擎是采用redis来做数据缓存层,引擎在以异步的方式(时间可配置,默认100ms)实现数据同步.为了提高redis的可扩展性.高可用性,把redis换成codis,因为codis有部分 ...