介绍

BCD码

BCD码的英文全称是Binary-Coded Decimal‎,简称BCD,按字面解释是二进制十进制代码,是一种二进制的数字编码形式。

常见的BCD码有8421BCD码,2421BCD码,5421BCD码,余3码以及格雷码等等。

在本文中,我们所采用的BCD码8421BCD码

8421码,即从左到右的二进制位权重分别为8、4、2、1。即

BCD码 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001
0 1 2 3 4 5 6 7 8 9

应用场景

数字时钟,需要十进制地显示时分秒;温度显示也需要十进制;次数显示也需要十进制······

错误例子

module func(i_data, o_data)
input wire [7:0] i_data;
output wire [11:0] o_data; assign o_data[11:8] = i_data / 100;
assign o_data[7:4] = i_data / 10 % 10;
assign o_data[3:0] = i_data % 10;
endmodule

这是我们在做算法题的时候用到的方法,而且Verilog是支持除法和取余运算的,但是这样会耗费太多资源。对于硬件设计来说,我们需要用适合硬件的方法。

8421码与二进制码的关系

对于4位二进制码,是逢16进位。而8421码是逢10进位。

因此,大于9的二进制码,加6就可以得到8421码。

移位加三法

首先给出步骤:(8位二进制数为例)

  • BCD码初始化为0。
  • 将原二进制码左移一位,左移出的一位添到BCD码的低位上。
  • 判断BCD码所对应的个,十,百位是否大于等于5,如果是则该段加3。
  • 继续重复以上步骤直到移位8次后停止。

总之,在移位的过程中,如果移位出的数值大于等于5,则将数值加3,再进行移位。对于n位二进制数,就进行n次移位。

例子

以二进制数 0111_1101为例,数值为125。

百位 十位 个位 二进制数
开始 4'b0000 4'b0000 4'b0000 8'b0111_1101
左移1 4'b0000 4'b0000 4'b0000 8'b1111_1010
左移2 4'b0000 4'b0000 4'b0001 8'b1111_0100
左移3 4'b0000 4'b0000 4'b0011 8'b1110_1000
左移4 4'b0000 4'b0000 4'b0111 8'b1101_0000
加3 4'b0000 4'b0000 4'b1010 8'b1101_0000
左移5 4'b0000 4'b0001 4'b0101 8'b1010_0000
加3 4'b0000 4'b0001 4'b1000 8'b1010_0000
左移6 4'b0000 4'b0011 4'b0001 8'b0100_0000
左移7 4'b0000 4'b0110 4'b0010 8'b1000_0000
加3 4'b0000 4'b1001 4'b0010 8'b1000_0000
左移8 4'b0001 4'b0010 4'b0101 8'b0000_0000

可以看到,最终结果为 12'b0001_0010_0101。按照8421BCD码解析,即为125。

为什么要大于等于5

之前的联系不是说,大于9嘛?其实这只是一个简单的运算前后顺序关系。

BCD码是4位二进制数表示一个十进制数的1位,如果大于等于5,比如5,4'b0101,下一次移位后变成了4’b1010,而BCD码中是没有4’b1010的,所以要加6,向高位进位。(见联系)

所以移位后加6和移位前加3都是可以的。

具体实现

实现一

RTL结构

  • bin[7:0]:二进制数输入
  • bcd[11:0]:8421BCD码输出,[11:8] 为百位,[7:4] 为十位,[3:0] 为个位。
  • 该模块调用8次移位加3模块,如图:

代码

移位加3模块
module shift(i_data, o_data);
input wire [19:0] i_data;
output wire [19:0] o_data; wire [19:0] shift_data; assign shift_data[19:16] = i_data[19:16] > 4'd4 ? i_data[19:16] + 4'd3 : i_data[19:16];
assign shift_data[15:12] = i_data[15:12] > 4'd4 ? i_data[15:12] + 4'd3 : i_data[15:12];
assign shift_data[11:8] = i_data[11:8] > 4'd4 ? i_data[11:8] + 4'd3 : i_data[11:8];
assign shift_data[7:0] = i_data[7:0]; assign o_data = shift_data << 1'b1; endmodule
顶层模块
module bin2bcd(bin, bcd);
input wire [7:0] bin;
output wire [11:0] bcd; wire [19:0] w_0;
wire [19:0] w_1;
wire [19:0] w_2;
wire [19:0] w_3;
wire [19:0] w_4;
wire [19:0] w_5;
wire [19:0] w_6;
wire [19:0] w_7; shift shift_ins0 (.i_data({12'd0, bin}), .o_data(w_0));
shift shift_ins1 (.i_data(w_0), .o_data(w_1));
shift shift_ins2 (.i_data(w_1), .o_data(w_2));
shift shift_ins3 (.i_data(w_2), .o_data(w_3));
shift shift_ins4 (.i_data(w_3), .o_data(w_4));
shift shift_ins5 (.i_data(w_4), .o_data(w_5));
shift shift_ins6 (.i_data(w_5), .o_data(w_6));
shift shift_ins7 (.i_data(w_6), .o_data(w_7)); assign bcd = w_7[19:8]; endmodule

实现二

  • inData[15:0]:二进制数输入
  • outData[19:0]:8421BCD码输出,个十百千位同理。
  • 本代码通过循环实现。

代码

module   BinaryToBCD(
input wire [16-1:0] inData, //二进制输入
output wire [16+3:0] outData //BCD输出
);
parameter bit_binary = 16; //二进制数据位数
reg [bit_binary-1:0] bin;
reg [bit_binary+3:0] ShiftReg;
always@(inData)
begin
bin = inData;
ShiftReg = 'd0;
repeat (bit_binary - 1)
begin
ShiftReg[0] = bin[bit_binary-1];
//adjust by add 3
if(ShiftReg[19:16] > 4)
ShiftReg[19:16] = ShiftReg[19:16] + 2'd3;
else
ShiftReg[19:16] = ShiftReg[19:16];
if(ShiftReg[15:12] > 4)
ShiftReg[15:12] = ShiftReg[15:12] + 2'd3;
else
ShiftReg[15:12] = ShiftReg[15:12];
if(ShiftReg[11:8] > 4)
ShiftReg[11:8] = ShiftReg[11:8] + 2'd3;
else
ShiftReg[11:8] = ShiftReg[11:8];
if(ShiftReg[7:4] > 4)
ShiftReg[7:4] = ShiftReg[7:4] + 2'd3;
else
ShiftReg[7:4] = ShiftReg[7:4];
if(ShiftReg[3:0] > 4)
ShiftReg[3:0] = ShiftReg[3:0] + 2'd3;
else
ShiftReg[3:0] = ShiftReg[3:0];
ShiftReg = ShiftReg << 1;
bin = bin << 1;
end
ShiftReg[0] = bin[bit_binary-1];
end
assign outData = ShiftReg;
endmodule

参考文献

[1] https://blog.51cto.com/u_15076212/3816404 "基于FPGA的二进制转BCD设计与实现(移位加3法)"

[2] https://zhuanlan.zhihu.com/p/209083141 "[走近FPGA]之二进制转BCD码"

FPGA移位加三法的更多相关文章

  1. 我的 FPGA 学习历程(07)—— BCD 编码:移位加 3 算法

    2-10 进制码,也称为 BCD 码,它的编码方式则是通过一个 4 位二进制来表示一个 10 进制数,部分十进制对应的 BCD 码如下 十进制数 | BCD 码 13 --> 0001_0011 ...

  2. fpga板制作调试过程记录

    2010-09-11 22:49:00 昨天淘宝准备买块fpga核心板学习,为了练习焊接,我让老板给我散料及pcb板自己焊接. 一,在物料到之前的准备: 我先设计了一下焊接测试计划 1,检查电路板:特 ...

  3. 如何对xilinx FPGA进行bit文件加密

    记录背景:最近在用Vivado评估国外一个公司所提供的ISE所建的工程时,由于我并没有安装ISE工程,因此将其提供的所有v文件导入到Vivado中,对其进行编译.添加完之后成功建立顶层文件,但奇怪的是 ...

  4. Altera FPGA 远程升级有关的几个IP的使用

    在做在线远程升级的时候,一般需要两步:1.将数据写到外挂的flash中.2重新启动FPGA配置. 不过要做到远程升级,一般需要在原始程序中就考虑到加入远程升级模块,remote updata IP, ...

  5. FPGA设计中遇到的奇葩问题之“芯片也要看出身”

    FPGA设计中遇到的奇葩问题之“芯片也要看出身”(一) 昨夜西风凋碧树.独上高楼,望尽天涯路 2000年的时候,做设计基本都是使用Xilinx公司的Virtex和Virtex-E系列芯片.那时候Alt ...

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

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

  7. GSM BTS Hacking: 利用BladeRF和开源BTS 5搭建基站

    引文 如果你已经购买了Nuand(官方)BladeRF x40,那么就可以在上面运行OpenBTS并可以输入一些指令来完成一些任务.一般来说HackRF,是一款覆盖频率最宽的SDR板卡.它几乎所有的信 ...

  8. 20140704笔试面试总结(java)

    1.java数组定义 1.与其他高级语言不同,Java在数组声明时并不为数组分配存储空间,因此,在声明的[]中不能指出数组的长度 2.为数组分配空间的两种方法:数组初始化和使用new运算符 3.未分配 ...

  9. 列式数据库~clickhouse 底层存储原理

    简介:今天介绍列式数据库的一些基本原理 一  数据目录 Data目录 数据存储目录,数据按照part分成多个文件夹,每个文件夹下存储相应数据和对应的元信息文件 Metadata 表定义语句,存储所有表 ...

  10. A Simple Note on "P4FPGA: A Rapid Prototyping Framework for P4"

    论文:P4FPGA: A Rapid Prototyping Framework for P4 Github:https://github.com/p4fpga Reference: Han Wang ...

随机推荐

  1. java无效发源版本xx

    这三个地方统一一下 就可以解决了

  2. YOLO2论文中文版

    文章目录 YOLO9000中文版 摘要 1. 引言 2. 更好 3. 更快 4. 更强 5. 结论 参考文献 YOLO9000中文版 摘要 我们引入了一个先进的实时目标检测系统YOLO9000,可以检 ...

  3. KMP算法学习笔记

    总算把这个东西搞懂了...... KMP是一个求解字符串匹配问题的算法. 这个东西的核心是一个\(next\)数组,\(next_i\)表示字符串第\(0\sim i\)项的相同的前缀和后缀的最大长度 ...

  4. 【Vue2】NavigationDuplicated: Avoided redundant navigation to current location:xxxxx

    翻译过来就是,导航重复:避免了到当前位置的冗余导航. 简单来说就是重复跳转了相同路径 原因 触发这种情况是因为vue-router中引入了primise,当传递了多次重复的参数就会抛出异常,而这种问题 ...

  5. 2022-07-09:总长度为n的数组中,所有长度为k的子序列里,有多少子序列的和为偶数?

    2022-07-09:总长度为n的数组中,所有长度为k的子序列里,有多少子序列的和为偶数? 答案2022-07-09: 方法一:递归,要i还是不要i. 方法二:动态规划.需要两张dp表. 代码用rus ...

  6. 2021-08-18:扰乱字符串。使用下面描述的算法可以扰乱字符串 s 得到字符串 t :1.如果字符串的长度为 1 ,算法停止。2.如果字符串的长度 > 1 ,执行下述步骤:在一个随机下标处将字符串

    2021-08-18:扰乱字符串.使用下面描述的算法可以扰乱字符串 s 得到字符串 t :1.如果字符串的长度为 1 ,算法停止.2.如果字符串的长度 > 1 ,执行下述步骤:在一个随机下标处将 ...

  7. Django笔记四十之运行Django环境的python脚本

    本文首发于公众号:Hunter后端 原文链接:Django笔记四十之运行Django环境的python脚本 这一篇笔记介绍如何在 Django 中运行脚本. 假设说我们要实现一个功能,需要获取 blo ...

  8. flex弹性布局模式下文字超出显示省略号

    都知道flex弹性布局非常好用,会随分辨率不同,宽高自适,那怎么来设置在一定范围内的文字超出隐藏,显示省略号呢?其实也不难 看如下就是使用flex布局的 其实如上效果也同样离不开如下三句,只是用法不大 ...

  9. 代码随想录算法训练营Day20 二叉树| 235. 二叉搜索树的最近公共祖先 701.二叉搜索树中的插入操作 450.删除二叉搜索树中的节点

    代码随想录算法训练营 235. 二叉搜索树的最近公共祖先 题目链接:235. 二叉搜索树的最近公共祖先 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先. 百度百科中最近公共祖先的定义为:& ...

  10. 人工智能导论——口罩佩戴检测详解(附带MTCNN论文精读)

    人工智能导论--口罩佩戴检测详解(附带MTCNN论文精读) 一.问题重述 随着人类的科技不断进步,病毒也在随之更新迭代:在19年席卷全球的新冠肺炎疫情给人们的生活带来了极大的灾难,造成了无数的人因此失 ...