注:本文由不愿透露姓名的 @Bulingxx 撰写。以下为正文。

在上一篇文章中介绍了数码管如何在FPGA开发板上实现动态显示,其文章链接如下:

人生状态机:[走近FPGA]之数码管动态显示​zhuanlan.zhihu.com

本文的所有实例都使用硬木课堂Xilinx Aritx 7 FPGA板实现,且附有上板演示视频,该开发板的链接如下:

硬木课堂 Xilinx Aritx 7 FPGA板 Arm Cortex-M SoC设计 集创赛​item.taobao.com

在这篇文章中,结合模块化的思想,通过分享一个二进制转BCD码的实例向大家简单介绍算法是如何在FPGA上实现的,并向大家简单介绍一种简单testbench实现自动化验证的写法。

BCD码

在数字逻辑设计课程中,我们已经学过了BCD码的相关知识,它用4位二进制数来表示1位十进制数中的0~9,是二进制编码的十进制代码,常见的BCD码有8421BCD码,2421BCD码,5421BCD码,余3码以及格雷码等等。在这篇文章中,我们所采用的BCD码为8421BCD码,8421BCD码各位的权值为8、4、2、1,用0000~1001表示十进制数,其它几种BCD码编码方式在这里不过多赘述。

二进制转BCD码(加3移位法)动态显示实例

本文实现一个二进制转十进制的电路,8位拨码开关(SW7-SW0)作为一组8位二进制输入信号,拨码开关SW11作为复位开关,拨码开关SW10作为使能开关,将8位二进制输入转为3位十进制表示,经由数码管动态显示输出。

实现这样的一个效果,可以先大致的将电路分为二进制转化和数码管显示两个部分,框架如下图所示,本篇文章主要讲述二进制转化部分。

二进制转BCD码动态显示框架

二进制转BCD码看起来最简单的方法是用除法运算来获得百位、十位、个位上的值,但实际上这种方式取模会占用过多资源,底层电路设计十分复杂,这告知我们选择合适的算法对于系统是有很大帮助的,因此通常使用加3移位法实现二进制转BCD码。

在这里简单介绍一下加3移位法的原理。我们知道,四位二进制大于15才进位,而8421BCD码是大于9就进位,若四位二进制大于9时进位,这样得到的就是15的BCD码,因此将大于9的四位二进制数加6就能得到其BCD码。对于大于四位的二进制数,通过左移,逢9加6进位,即可转换任意位的二进制数,比如说,对于5位二进制数,由高4位二进制数左移一位得到,那么将前4位得到的BCD码也左移一位,并重新判断低四位是否大于9,若大于9,则加6进位,即可得到5位二进制数对应的BCD码。

加3移位法相比与加6移位法在算法上的结果是等效的,但占用的资源更小,相比于加6移位法先移位,再判断低4位是否大于9,加3移位法是先判断低四位是否大于4,再进行移位。值得一提的是,加3移位法对于最后的低4位而言无需判断低4位是否大于4,因为已经没有移位操作了。

参考网上的一个将八位二进制数255,将其转为8421BCD码的例子给大家加以说明。

0           1111 1111;          //原数
1           0000 0001;          //左移一次
2           0000 0011;          //左移二次
3           0000 0111;          //左移三次,检查低四位>4?
3.1.        0000 1010;          //大于4,加3进行调整
4           0001 0101;          //左移四次,检查低四位>4?
4.1.        0001 1000;          //大于4,加3进行调整
5           0011 0001;          //左移五次
6           0110 0011;          //左移六次,检查高四位>4?
6.1.        1001 0011;          //大于4,加3进行调整
7           1 0010 0111;         //左移七次,检查低四位>4?
7.1.        1 0010 1010;         //大于4,加3进行调整
8           10 0101 0101;        //左移八次(得到BCD码255)

理解了算法,接下来就是如何实现算法。实现同样功能有不同的算法,同样的,实现算法也有各式各样的电路。如何让实现的电路简单有效,就是FPGA工程师的价值所在。直白的看来,实现加3移位法,需要通过寄存器进行若干次的移位,并判断检查是否需要进位,这样“简单粗暴”实现的电路,完成一组数据的转化需要经过多个时钟周期,电路实际上也较为复杂。在这里,针对8位二进制数,我们实现的加3移位法电路结构如下图所示。

加3移位法电路

在这个电路中,Adder模块实现输入大于4就加3进位的功能,再通过人为的“移位”操作,就实现了加3移位法。具体实现过程可以理解为,首先,0和高三位(a7、a6、a5)的数据构成左移三次后的低四位二进制数据,经过Adder1模块后,得到调整后的数据;调整后数据的低三位和a4构成左移四次后的低四位数据,这四位数据作为Adder2模块的输入,就实现了“移位”,再通过Adder2进行调整数据即可;Adder3部分与Adder2部分一致,实现了左移五次的数据修正;这时,经过Adder1、Adder2和Adder3处理后的数据与a2构成了左移六次的数据,这七位有效数据的高三位可能会大于4,因而高四位和低四位都需要进行数据的调整,也就是分别通过Adder4和Adder5来修正;Adder6和Adder7与Adder4和Adder5一致,实现左移七位后的数据调整;最后,在高位填0并与最低位的a0构成最终左移八次的十二位数据。

Adder模块的功能为当输入大于4时,加3调整,当输入小于等于4时,保持原值,其电路结构如下,通过比较器,多路选择器和加法器实现功能。

Adder电路

数码管动态显示模块可以参考上一篇数码管动态显示文章加以理解,根据上一篇文章的实例一和实例二,我们可以得到这样的一个数码管动态显示模块。

数码管动态显示电路框图

下面给出各部分RTL代码。

如下是二进制转BCD码模块的RTL代码,通过七个adder3模块以及人为的移位实现转换。

module 

下面是adder3模块的代码,通过case语句实现功能。

module 

接下来是动态显示的各部分代码,与上篇文章相同不赘述。

首先是时钟分频模块。

module 

计数器模块。

module 

寄存器模块。

module 

三选一多路复用器模块。

module 

数码管位选。

module 

数码管段码。

module 

最后是顶层文件的编写,将各个功能模块例化并进行正确的连接。

module 

借助Vivado的RTL分析功能得到对应RTL代码的电路原理图,如下图所示,能直观地看到各部分子模块及其连接方式。

RTL分析电路原理图

在完成上述步骤后,接下来对二进制转BCD码模块进行功能仿真,验证其功能的正确性。Testbench实际上是一种验证手段,通过一种具有输入激励和输出校验的虚拟平台来进行软件层次的分析和校验。

TestBench结构图

上图所示为一种简单Testbench的结构,在这个模块中行为级描述和RTL级描述是对同一功能的不同层次描述,二者的区别在于RTL级是可综合的,而行为级是为了得到结果,不关心电路结构,只注重算法,可以通过C/C++来描述。通过向两种描述方式给予足够的输入激励,就可以根据输出结果来判断我们的RTL级描述功能是否正确。

从结构图上我们也可以看出,这种结构适用于像二进制转BCD码这样直接计算的逻辑设计,但对于逻辑设计中具有复杂反馈和控制的,便需要通过UVM复杂验证框架来设计测试的结构。

下面给出Testbench模块的代码,从0不断递增1作为测试输入,来向两个描述模块进行赋值并输出结果,当二者的所有输出结果都一致时,输出“Accept”说明功能正确,否则会输出“Wrong Answer”,表明存在问题。

`timescale 

下图是Testbench在Modelsim中的仿真波形,比对输入和两种描述下的输出结果,可见两者输出一致。

TestBench仿真波形

在Transcript窗口看到输出“Accepted”,表明电路功能正确。

Transcript窗口输出结果

完成仿真后,就可进行后续的综合、管脚约束、布局布线以及生成比特流文件,本例具体的管脚约束如下表所示。

管脚约束

下面为一段该实例的上板演示视频。

知乎视频​www.zhihu.com

至此,使用加3移位法实现8位二进制转BCD码并进行动态显示的实例分享结束。在这篇文章中,借助这个实例向大家介绍了加3移位法的原理,及其如何在FPGA中得以实现,实际上实现方法有很多,而如何使得实现的电路既符合需求而又简单正是FPGA工程师的魅力所在,此外,也向大家简单介绍了一种用于没有复杂反馈和控制的逻辑设计的简单TestBench的写法。通过这篇文章,希望能够帮助大家进一步掌握模块化的思想以及理解在FPGA如何实现算法电路。

8086汇编4位bcd码_[走近FPGA]之二进制转BCD码相关推荐

  1. 矩阵键盘与六位数码管_[走近FPGA]之矩阵键盘

    注:由于新学期较为繁忙,本文由不愿透露姓名的 @Cardia 撰写.以下为正文. 在上一篇文章中,介绍了二进制转十进制电路的实现,其文章链接如下: 人生状态机:[走近FPGA]之二进制转BCD码​zh ...

  2. 优酷视频怎么转二维码_优酷视频转二维码

    有的人想将自己制作的视频分享出去,那么该如何将视频转换成二维码来分享呢?其实方法很简单,直接在视频界面中就能生成,这里和大家讲讲. 01. 登录自己的优酷帐号,然后点击右上角的上传按钮. 优酷视频怎么 ...

  3. FPGA零基础学习:基于FPGA的二进制转BCD设计(附代码)

    FPGA零基础学习:基于FPGA的二进制转BCD设计(附代码) 本系列将带来FPGA的系统性学习,从最基本的数字电路基础开始,最详细操作步骤,最直白的言语描述,手把手的"傻瓜式"讲 ...

  4. 8086汇编4位bcd码_238期中4头3尾,排列五第19239期爱我彩规

    爱我彩规 专业研究(七星彩.排列五)  前四位的铁码与定位规,有幸开通爱我彩规公众号,努力为大家提供稳定的号码参考.作者微信号awc1125. 逢星期二和星期天不在彩码课堂公众号转发,因星期二和星期天 ...

  5. fpga供电电压偏低会怎样_[走近FPGA]之开发板介绍篇

    开发板概述 在走近FPGA预告篇中,我们已经提到了系列文章使用的开发平台,硬木课堂Xilinx Artix 7 FPGA板,如下图所示.它使用的FPGA芯片型号为Xilinx Artix-7 XC7A ...

  6. 生成有时间限制的二维码_微信公众号渠道二维码怎么制作?监测渠道效果的利器来了...

    每逢营销节点,各种渠道推广少不了,非常时刻需要能够统计不同渠道二维码的数据情况. 微信引流效果好不好怎么判断?新增人数为什么一团乱麻?粉丝又分别是从哪个渠道来的? 用渠道二维码就能搞定这些问题. 一. ...

  7. python制作二维码_基于Python生成个性二维码过程详解

    一.问题描述 通过调用MyQR模块来实现生成个人所需二维码. 安装: pip install myqr 二.代码实现 1.普通二维码 from MyQR import myqr # 普通二维码 myq ...

  8. python输出字符的ascii码_如何获取一个字符的ASCII码

    如何获取一个字符的ASCII码 Python内置ord函数 用来将字符转化成ASCII码 用法为: print('字符0 的ASCII码表示为',ord('0')) 结果为: 字符0 的ASCII码表 ...

  9. GOOGLE ADSENSE广告联盟收不到PIN码_快速表单身份验证PIN码方法

    在自己的网站或者博客上投放Google Adsense广告是目前很多站长不错的赚钱途径.尤其是Google Adsense不仅单价高.而且信誉好.支付稳定等天然优势让国内众多广告联盟黯然失色.在流量有 ...

最新文章

  1. python的 局部变量与全局变量
  2. 高性能Sqlite存储模型对象解密
  3. 杭电2030java做法_杭电ACM2040java做法
  4. 俄罗斯研发替身机器人,危险工作无需真人
  5. 001-引入layui和layui.code方法
  6. AtCoder AGC039F Min Product Sum (容斥原理、组合计数、DP)
  7. FTP开启被动连接模式
  8. 对scala函数总结
  9. codeforces 719A Vitya in the Countryside(序列判断趋势)
  10. python邮件发送脚本
  11. wiley 期刊Stix字体问题
  12. CBA离好生意还差几个NBA?
  13. 数据分析之实战项目——电商用户行为分析【python】
  14. 我们需要“梦想比回忆多”的精神
  15. 如何创建 “抢占实例” 云服务器BCC?抢占式实例云服务器创建步骤
  16. Python全栈开发【基础-09】深浅拷贝+while循环
  17. html5播放推流播放地址是黑屏的,OBS Studio直播推流显示黑屏怎么办?教你解决方法...
  18. 王冰玉时代曙光科技 丽江-稻城-理塘-丹巴-康定-成都“中心"穿越小卡片之旅...
  19. laravel配置语言包,实现网站中英文切换
  20. js 百度地图标记定位(一)

热门文章

  1. python复制excel模板并保留表格样式
  2. Spark:利用tac+cellid基站定位
  3. 苹果切换输入法_iPhone输入法的正确打开方式,让你打字更痛快
  4. csp试题2:ISBN号码
  5. js实现小球抛物线运动
  6. 云服务器部署项目环境搭建
  7. 2014世界杯预测与开源大数据
  8. 计算机原理学习(序)
  9. 10.24 每日学习打卡
  10. mingw64亲测有效版本,直接解压,无需安装