基础项目(10)BCD转二进制程序设计讲解

写在前面的话

在前面小节的学习中,我们已经掌握了将二进制数转换成BCD码的方法。那么现在我们就反过来思考一下,设计一个什么样的电路,才可以将BCD码转换成二进制数呢?

基本概念

在数学中,我们都知道随便一个十进制数如5468 ,那么它的计算过程可以转换为:5468= 5*1000+4*100+6*10+8,因此BCD码转成二进制数的算法就是:

abcd = a*1000 + b*100 + c*10 +d

这种算法是最常规的一种算法,里面需要用到乘法器以及加法器,这种实现方式比较耗费资源,下面梦翼师兄会介绍一种算法,这种算法需要用到加法和移位来完成BCD转二进制数的功能,从而尽可能的节约逻辑资源。

移位算法原理

在介绍这种算法之前,梦翼师兄先来解释一个小小的问题:二进制码左移一位等于未左移的二进制码*2,例如有二进制码101001,转成十进制等于41,左移一位得到1010010,转成十进制等于82。

也就是说二进制码左移1位加上左移3位可以等效于二进制码乘以10,那么我们是否可以利用移位来代替乘法的运算呢?下面我们就来设计一个电路将输入的3位bcd码转换成二进制码,来实现BCD码转二进制数的功能。

顶层框图

顶层模块端口介绍


端口名


端口说明


clk


系统50MHz时钟输入


rst_n


系统低电平复位


bw


BCD码百位输入


shiw


BCD码十位输入


gew


BCD码个位输入


binary


输出转换后的二进制数

代码实现


/****************************************************

*   Engineer      :   梦翼师兄

*   QQ             :   761664056

*   The module function: BCD码转二进制数模块 *****************************************************/

01  module bcd_to_bin(

02              clk,   //系统50Mhz时钟

03              rst_n, //系统低电平复位

04              bw,   //输入的BCD码的百位

05              shiw,  //输入的BCD码的十位

06              gew,   //输入的BCD码的个位

07              binary //输出的二进制数

08              );

09

10  input clk;

11  input rst_n;

12  input [3:0] bw;  //百位

13  input [3:0] shiw; //十位

14  input [3:0] gew;  //个位

15

16  output [9:0] binary; //转换结果

17

18  reg [9:0] bwValue1; //百位BCD码转换寄存器1

19  reg [9:0] bwValue2; //百位BCD码转换寄存器2

20  reg [9:0] bwValue3; //百位BCD码转换寄存器3

21  reg [9:0] shiwValue1; //十位BCD码转换寄存器1

22  reg [9:0] shiwValue2; //十位BCD码转换寄存器2

23  reg [9:0] gewValue;    //个位BCD码转换寄存器

24

25  /***********转换操作*******************/

26  always @(posedge clk or negedge rst_n)

27  if (!rst_n)

28      begin //寄存器赋初值

29          bwValue1 <= 0;

30          bwValue2 <= 0;

31          bwValue3 <= 0;

32          shiwValue1 <= 0;

33          shiwValue2 <= 0;

34          gewValue <= 0;

35      end

36  else

37      begin

38      //由我们得出的规律可知:a*100=a*(64+32+4)=a*64+a*32+a*4

39      //=a000000+a00000+a00,即a左移6位加上左移5位加上a左移2位

40          bwValue1 <= bw<<6;

41          bwValue2 <= bw<<5;

42          bwValue3 <= bw<<2;

43      //由我们得出的规律可知:a*10=a*(8+2)=a*8+a*2 =a000+a0,

44      //即a左移3位加上左移1位

45          shiwValue1 <= shiw<<3;

46          shiwValue2 <= shiw<<1;

47          gewValue <= gew; //个位数据不变

48      end

49  //将所有的各个位的转换结果相加就是转换后的二进制数

50  assign binary = bwValue1 + bwValue2 + bwValue3 + shiwValue1

51                  + shiwValue2 + gewValue;

52

53  endmodule

第18~23行我们定义了BCD码转换需要用到的寄存器,因为我们从算法原理这一部分中总结的规律是:百位的BCD码转换需要(a*100=a*(64+32+4)=a*64+a*32+a*4=a000000+a00000+a00,即a左移6位加上左移5位加上a左移2位)三部分组成,所以需要三组寄存器,同理十位和个位也分别需要两组和一组寄存器;37~48行测试执行移位操作,50~51行将移位的结果输出。

 测试代码如下:


/****************************************************

*   Engineer      :   梦翼师兄

*   QQ             :   761664056

*   The module function: BCD码转二进制数测试模块 *****************************************************/

01  `timescale 1ns/1ps

02

03  module bcd_to_bin_tb;

04

05      reg clk;

06      reg rst_n;

07      reg [3:0] bw;   //百位

08      reg [3:0] shiw; //十位

09      reg [3:0] gew;  //个位

10

11      wire [9:0] binary;

12

13      initial begin

14          clk = 0;

15          rst_n = 0;

16         bw = 4‘d0; shiw = 4‘d0; gew = 4‘d0;

17          #1000 rst_n = 1;

18

19          #100 bw = 4‘d1; shiw = 4‘d2; gew = 4‘d0; //120

20          #100 bw = 4‘d3; shiw = 4‘d2; gew = 4‘d9; //329

21          #100 bw = 4‘d7; shiw = 4‘d0; gew = 4‘d3; //703

22          #100 bw = 4‘d0; shiw = 4‘d2; gew = 4‘d7; //027

23          #100 bw = 4‘d2; shiw = 4‘d9; gew = 4‘d0; //290

24

25      end

26

27      always #10 clk = ~clk;

28

29       bcd_to_bin bcd_to_bin(

30        .clk(clk),         //系统50Mhz时钟

31        .rst_n(rst_n),   //系统低电平复位

32        .bw(bw),         //输入的BCD码的百位

33        .shiw(shiw),     //输入的BCD码的十位

34        .gew(gew),       //输入的BCD码的个位

35        .binary(binary)  //输出的二进制数

36       );

37

38  endmodule

我们在测试代码中写入了5组BCD码来检测输出是否正确

仿真分析

从仿真图可以看出,分别输入5组BCD码:120、329、703、27、290,观察输出可知转换之后的二进制数是正确的,成功的把BCD码转换成了二进制码。所以本次设计是成功的。

原文地址:https://www.cnblogs.com/mengyi1989/p/11521080.html

时间: 2024-08-13 18:25:05

基础项目(10)BCD转二进制程序设计讲解的相关文章

基础项目(3)三态门程序设计讲解

写在前面的话 我们所接触到的IO都是单纯的输入(input)或者输出(output)类型,而我们的一些总线协议如IIC等,要求信号为三态类型,也就是我们所说的输入输出(inout)类型.那么,本节梦翼师兄将和大家一起来探讨三态门的用法. 项目需求 设计一个三态门电路,可以实现数据的输出和总线“挂起”. 系统架构 模块功能介绍 模块名 功能描述 three_state 控制三态总线Sda是否处于挂起状态 顶层模块端口描述 端口名 端口说明 Clk 系统时钟 Rst_n 系统低电平复位 Data_b

进阶项目(4)蜂鸣器程序设计讲解

写在前面的话 经过前面内容的学习,梦翼师兄相信大家的基础知识水平一定已经很扎实.那么本节,我们就一起来庆祝一下,用播放器奏响一曲<欢乐颂>,奏响我们凯旋的乐章. 什么是蜂鸣器? 蜂鸣器是一种一体化结构的电子讯响器,采用直流电压供电,广泛应用于计算机.打印机.电子玩具.定时器等电子产品中作为发声器件.蜂鸣器分为有源蜂鸣器和无源蜂鸣器两种,在电路中用字母“H”或“HA”(旧标准用“FM”.“ZZG”.“LB”.“JD”等)表示.那么,怎么区分有源蜂鸣器和无源蜂鸣器呢?有源蜂鸣器内部带震荡源,所以只

linux基础学习-10.1-特殊符号-分类讲解

1.重定向符号 01.> 输出重定向 先清空文件,追加 02.>> 追加输出重定向 追加 03.< 输入重定向 与 xargs tr 04.<< 追加输入重定向 cat 向一个文件追加多行. cat >>/oldboy/alex.txt<<EOF Love me, love my dog. Love Li, love li's dog. EOF 2. 表示位置的 01. .(点) 当前目录 02. .. 当前目录上一级目录 03. ~ 当前用户的

C语言零基础项目驱动式学习第一天

引言: 智能手机(Smart Phone)是一种运算能力及功能比传统手机更强的手机.目前的操作系统基本上有以下几种: 1. Symbian Os 众所周知塞班隶属于NOKIA,Symbian开发之初的目标是保证在较低资源的设备上能长时间的运行,这导致了塞班的应用程序开发有着较为陡峭的学习路线,开发成本高,但是程序的运行的效率很高> 2.Android 开源, 联盟,Android凝聚了几乎遍布全球的力量,这是Android形象及声音能够被传到全球移动互联网市场每一个角落的根本原因.不过, 1).

bcd转二进制

BCD码用于显示,但是计算器内部计算用的是二进制码,所以有的时候要对其进行转换. 最简单的BCD转二进制的方法是什么呢? 我们知道BCD码每4位表示一个10进制数,我们现在假设num_reg是一个16位的BCD码,也就是4位的十进制数.那么num_reg[15:12]表示这个数的最高位,他的权值是1000,这个应该可以理解吧.同样的道理,num_reg[11:8]的权为100,num_reg[7:4]的权为10,num_reg[3:0]的权为1. 所以bin = num_reg[15:12] *

C语言零基础项目驱动式学习第四天

//类型修饰符  数组名[数组元素个数] = {初始化}; //定义数组的时候[]中必须是常量表达式, 不可以是变量; /* int age[5] = {21, 18, 25, 20, 18}; int array[10] = {0};//代表数组中有10个元素, 每个都是0; int array1[8] = {1};//代表数组中有8个元素,第一个是1,其余的为0; int age2[2 + 3] = {0}; */ //定义数组和使用数组的最大区别是, 前面是否有类型修饰符 //使用数组元素

C语言零基础项目驱动式学习第二天

//BOOL 类型是一种非真即假的数据类型,取值只有YES和NO, //BOOL 其实是OC中得数据类型,在C语言中,认为非0即为真. //BOOL 类型规定的存储空间为一个字节. //    BOOL a = YES; //    BOOL b = NO; //    printf("a = %d, b = %d\n", a, b); //    int a = 15, b = 18; //    BOOL c = a > b; //    printf("c = %

C语言零基础项目驱动式学习第三天

一 while循环二do   while循环三 for循环for循环的执行顺序用如下表达式: for(expression1;expression2;expression3)        循环变量初值; 循环条件; 循环变量增量  {                expression4; }       执行的顺序应该是: 1)第一次循环,即初始化循环.      首先执行表达式expression1(一般为初始化语句):再执行expression2(一般为条件判断语句),判断express

【项目实战派】触摸屏程序设计要点

[项目实战派]触摸屏程序设计要点            触摸屏作为一种更为直接的人机交互方式,现在广泛运用于智能手机.工业控制.场景展示等许多场合.作为程序员,如何理解触摸屏程序设计?如何做好的触摸屏程序设计?现在已经有的资源包括那些?借着项目牵引,我对这个问题进行一定探索,经验有限,欢迎批评交流. 一.如何理解触摸屏程序设计 操作系统层面已经实现了基础功能,基于触摸屏的界面,从本质上来说和普通的GuI界面是没有区别的.程序的界面设计需要服务于程序的功能,为客户提供直观.易用.体验效果较好的界面