• 基础项目(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码转换成了二进制码。所以本次设计是成功的。

  • 相关阅读:
    压缩与解压
    Ubuntu下搭建yocto
    Ubuntu 1804 进入紧急模式
    How To Configure NFS Client on CentOS 8 / RHEL 8
    Install and Configure NFS Server on RHEL 8 / CentOS 8
    结构体大小的计算
    SQL语句对数据库调优常用
    用SQL语句操作数据库高级
    windows命令行操作mysql
    创建方便的csv格式文件
  • 原文地址:https://www.cnblogs.com/mengyi1989/p/11521080.html
Copyright © 2020-2023  润新知