精华内容
下载资源
问答
  • 二进制转换bcd计算
    2021-07-05 09:23:34

    微机原理实验-二进制到BCD转换

    广州大学学生实验报告

    开课学院及实验室:实验中心

    学 院 机电 年级、专 业、班 微机原理实验

    2013 年 11 月 4 日

    姓名 学号 成绩 指导 教师

    实验课程名称 实验项目名称 一、实验目的

    二进制到 BCD 转换

    二、实验原理(实验相关基础知识、理论) 三、实验过程原始记录(程序界面、代码、设计调试过程描述等) 四、实验结果及总结 一、实验目的

    1.将给定的一个二进制数转换成二十进制(BCD)码。 2. 掌握简单的数值转换算法。 3. 基本了解数值的各种表达方法。

    二、实验原理(实验相关基础知识、理论)

    定义:用4位二进制数来表示1位十进制数中的0~9这10个数码,简称 BCD 码 即 BCD 代码。Binary-Coded Decimal ,简称 BCD,称 BCD 码或二-十进制代码,亦称二进 码十进数。是一种二进制的数字编码形式,用二进制编码的十进制代码。这种编码形式利 用了四个位元来储存一个十进制的数码,使二进制和十进制之间的转换得以快捷的进行。 这种编码技巧,最常用于会计系统的设计里,因为会计制度经常需要对很长的数字串作准 确的计算。相对于一般的浮点式记数法,采用 BCD 码,既可保存数值的精确度,又可免却 使电脑作浮点运算时所耗费的时间。此外,对于其他需要高精确度的计算,BCD 编码亦很 常用。 由于十进制数共有0、1、2、 、9十个数码,因此,至少需要4位二进制码来表示1位 十进制数。4位二进制码共有2^4=16种码组,在这16种代码中,可以任选10种来表示10个十 进制数码,共有 N=16!/(16-10) !约等于2.9乘以10的10次方种方案。常用的 BCD 代码列 于末。 常用 BCD 编码方式 最常用的 BCD 编码,就是使用"0"至"9"这十个数值的二进码来表示。这种编码方式,在 中国大陆称之为“8421码”。除此以外,对应不同需求,各人亦开发了不同的编码方法, 以适应不同的需求。这些编码,大致可以分成有权码和无权码两种: 有权 BCD 码,如:8421(最常用)、2421、5421 无权 BCD 码,如:余3码、格雷码

    1-1044-jpg_6_0_______-721-0-0-721.jpg

    更多相关内容
  • 目录写在前面正文快速认识实现方式一实现方式写在最后写在前面FPGA基础知识极简教程(9)讲到了七段数码管的显示Verilog设计,我们都知道,要在数码管上显示的数字,使用BCD编码是具有优势的(或者是最正确的)。...

    faba17eca77b79f9f4e55214f876eb60.png

    目录

    • 写在前面
    • 正文
      • 快速认识
      • 实现方式一
      • 实现方式二
    • 写在最后

    写在前面

    FPGA基础知识极简教程(9)讲到了七段数码管的显示Verilog设计,我们都知道,要在数码管上显示的数字,使用BCD编码是具有优势的(或者是最正确的)。拿数字时钟来说,如果你的时钟是12点,难道你会让数码管显示C? 如果你愿意如此,那就给自己家里安装一个这样的时钟吧! 如果是23点呢?不用BCD编码的数字恐怕不能显示了吧。 采用BCD码的数字,十位用一个数码管显示,个位用一个数码管显示,例如23点,则2和3分别显示,这样才符合人类的思维。

    尽管如此,存在这样一个问题,我们在设计计数器的时候,习惯于直接设计二进制计数器,这样的计数器计数结果是二进制的,我们需要将其转换成BCD码,这就是今天我们需要讨论的问题。

    当然,值得讨论的是这种方式是不是多此一举呢?如果仅仅对于数字时钟来说,时需要BCD编码的模24计数器,分以及秒则需要BCD编码的模60计数器。 这都很容易实现,例如上篇博客就是直接实现的BCD编码的模60以及模24计数器。之后送入数码管显示模块即可。 那么我们还有必要设计二进制转BCD码的必要吗? 有的!

    • 首先这是一种方法,也算经典,它的另外一个名字叫: Double-Dabble Binary-to-BCD Conversion Algorithm 我也不知道怎么翻译合适!
    • 其次,如果一个计数模块,即用到了二进制计数,又必须把它显示到数码管上,我们恐怕就不能直接将这个计数器设计为BCD码计数器了,更方便的方式是设计一个二进制计数器,需要显示的话,在调用二进制转BCD码模块,接入数码管显示模块即可。 你可能会说,可以设计一个BCD码计数器,之后转换成二进制! 呃,你认为这个工作量会小一点吗?
    • 最后,我认为这个算法还提供了一个思想,如何处理Verilog中的循环问题?

    我参考了互联网上的资料,形成了本文,这里将分享一种双重循环的设计方法,以及一种将循环转化为隐似的处理方法,也就是状态机的方式来实现!

    一起来看看吧。

    正文


    快速认识

    为了快速了解这个算法,我觉得先看一个小例子比较合适: 我们假设的二进制数为8位(11110011),如何将其转换为BCD码呢? 8位2进制数最大能表示的数字为255,用BCD码表示,需要12位来表示。上面的二进制数是1111_0011,对应的十进制为243,我们知道,它的BCD码形式为:0010_0100_0011。 有了这些先验知识,我们来看看如何转换的!

    首先,先将BCD码计数器清零,之后将二进制数和BCD码计数器统统左移,二进制数移出来的最高位放到BCD码计数器的最低位,如下表所示!

    ed05ecaf2c342692bb061942bd4f61d9.png

    每一次移位之后都判断下,BCD码计数器的十、分以及个位是否大于4,如果任何一位(4bit)大于4,则对其加3,之后继续移位,如此下去,直到移位次数为二进制数的位数之后,停止移位,此时得到的BCD码计数值便是转换后的值。

    实现方式一

    维基百科:给出了一种Verilog的实现方式:

    `timescale 

    该实现方式采用了双重循环的组合逻辑实现,我对其进行了行为仿真,如下:

    82aa728bad50aae93c2f211e8f40ea5f.png

    看起来貌似没有任何问题,但不得不考虑的是,行为仿真时不考虑延迟的,如果在实际的电路中,这种实现方式会不会影响时序呢? 答案几乎是肯定的,请看下面的RTL原理图,这种组合逻辑的延迟链很长!如果位宽更大,则延迟也随着增大。

    532034ee06f2b35a2b8e902430a42374.png

    实现方式二

    参考资料给出了一种状态机的实现方式。

    其原理也是: 它以输入的二进制数为起点。它将它一次移位一位到BCD输出向量中。然后,它将独立查看每个4位BCD数字。如果任何数字都大于4,则该数字将增加3。对于输入二进制向量中的每个位,此循环都会继续。请参见下图,以直观方式描述有限状态机的编写方式。

    be897b53e012ee817a88304cf7a79ba3.png

    根据此状态机以及转换原理,得到的Verilog设计为:

    module 

    需要注意两个位宽问题,一是输入二进制数的位宽INPUT_WIDTH,还有一个参数DECIMAL_DIGITS表示的是BCD码的个数,这里的个数指的是写成十六进制后的个数,每4位二进制数算一个。(表达真特么别扭)

    如果细心看这段代码的话,会发现状态机是真的强大,我们常听说一切皆可状态机,关键是你的状态机设计的是否正确,之后是否巧妙!

    代码中,从s_SHIFT状态到s_CHECK_DIGIT_INDEX 是构成循环的部分。如下:

    s_SHIFT 

    从状态转移图中也可以清晰看出这个循环:

    4638dc542999c0bdfe1ea2530419de72.png

    先对二进制以及BCD码寄存器进行移位,

    s_SHIFT 

    之后判断循环结束了吗?

    s_CHECK_SHIFT_INDEX 

    循环条件是循环次数,我们都知道,循环次数是二进制数的位数。 如果循环结束,则进入下一个状态s_BCD_DONE:

    s_BCD_DONE 

    在这个状态内,我们可以使用BCD值,r_DV是一个标志,有效则代表BCD值可以使用了。

    如果没有结束循环,则进入状态s_ADD,

    s_ADD 

    判断BCD码的个位是否大于4,如果大于4,则加3,之后进入状态:s_CHECK_DIGIT_INDEX

    s_CHECK_DIGIT_INDEX 

    如果BCD码只有个位,则进入s_SHIFT状态 ,移位,判断循环结束了没! 否则,还有十位,甚至百位,则继续进入s_ADD,判断是否大于4,如果大于4,加3,直到遍历了BCD的各个位(这里的位指的是4位二进制数组成的一位BCD码)。

    讲到这里,大概程序就没什么问题了。

    最后还需要注意的是,程序里面的输入输出,寄存器变量以及wire变量,以及参数的命名方式都遵循博文所提倡的代码风格

    做一个简单的仿真:

    仿真文件:

    `timescale 

    仿真波形:

    fa7ae8e3d0bcd24e2972a9e769f9e02e.png

    好了,就到这里吧,相信你已经很明白了。

    写在最后

    最近在忙毕业的事情,还有入职前租房子的各种事情,所以,博客落下了几天,断断续续地准备这个话题,终于可以发了一篇。 对了,这里面的代码也用到了一个2001之后新增语法:

    assign 

    可以在下面这篇博客里找到解释!有人说这个语法,花里胡哨,但是到今天,我发现这种用法很常见,因此,学着去用吧。

    参考资料语法解释

    最后的最后,推荐下我的微信公众号:FPGA LAB,可以关注我,没事,我都会每天推送文章,阅读更方便。

    展开全文
  • 浅谈BCD码同二进制转换

    千次阅读 2021-12-06 10:33:40
    一、BCD码 1、BCD码概述 2、BCD分类 1、有权码 2、无权码 3、BCD运算问题 二、二进制BCD码 1、原理实现 2、模块划分 3、仿真调试 4、仿真验证 三、BCD码转二进制 1、原理实现 2、模块划分 3、仿真验证

    一、BCD码

    1、BCD码概述

    • BCD码(Binary-Coded Decimal‎),用4位二进制数来表示1位十进制数中的0~9这10个数码,是一种二进制的数字编码形式,用二进制编码的十进制代码。BCD码这种编码形式利用了四个位元来储存一个十进制的数码,使二进制和十进制之间的转换得以快捷的进行。
    • 相对于一般的浮点式记数法,采用BCD码,既可保存数值的精确度,又可免去使计算机作浮点运算时所耗费的时间
    • BCD码也称二进码十进数,BCD码可分为有权码和无权码两类。其中,常见的有权BCD码有8421码、2421码、5421码,无权BCD码有余3码、余3循环码、格雷码。

    图片表示
    在这里插入图片描述

    流程详解:
    二进制数:1010 0010 = 2 5 + 2 7 + 2 1 = 2 + 32 + 128 = 162 2^5+2^7+2^1=2+32+128=162 25+27+21=2+32+128=162
    BCD码是用四位二进制数表示十进制数【0~9】
    0001 = 2 0 = 1 2^0=1 20=1
    0110= 2 2 + 2 1 = 6 2^2+2^1=6 22+21=6
    0010= 2 1 = 2 2^1=2 21=2

    2、BCD分类

    BCD码可分为有权码和无权码两类。其中,常见的有权BCD码有8421码、2421码、5421码,无权BCD码有余3码、余3循环码、格雷码

    • 有权码,自然二进制代码是按照二进制代码各位权值大小,以自然向下加一,逢二进一的方式来表示数值的大小所生成的代码。
    • 有权码和无权码区别是每一位是否有权值。

    1、有权码

    8421
    8421 BCD码是最基本和最常用的BCD码,它和四位自然二进制码相似,各位的权值为8、4、2、1,故称为有权BCD码。和四位自然二进制码不同的是,它只选用了四位二进制码中前10组代码,即用0000~1001分别代表它所对应的十进制数,余下的六组代码不用。
    运算规则:

    十进制0123456789
    二进制(BCD8421)0000000100100011010001010110011110001001
    按权相加0 2 0 2^0 20 2 1 2^1 21 2 1 + 2 0 2^1+2^0 21+20 2 2 2^2 22 2 2 + 2 0 2^2+2^0 22+20 2 2 + 2 1 2^2+2^1 22+21 2 2 + 2 1 + 2 0 2^2+2^1+2^0 22+21+20 2 3 2^3 23 2 3 + 2 0 2^3+2^0 23+20

    实例验证:

    十进制数: 4 + 3 = 7 4+3=7 4+3=7
    二进制数: 0100 + 0011 = 0111 0100+0011=0111 0100+0011=0111

    /*二进制加法:逢二进一 */
         0 1 0 0    4
       + 0 0 1 1    3
    
         0 1 1 1    7
    

    5421

    十进制0123456789
    二进制(BCD5421)0000000100100011010010001001101010111100

    2421

    十进制0123456789
    二进制(BCD2421)0000000100100011010010111100110111101111

    总结:
    有权码就是对应数字为对应位的权值,1代表可以取到该值,0表示取不到。
    8421:十进制数:5 二进制数:0101 即4和1能取到 4 + 1 = 5 4+1=5 4+1=5
    5421: 十进制数:5 二进制数:1000 即5能取到 5 5 5
    2421:十进制数:9 二进制数:1111即2和4和2和1都能取到 2 + 4 + 2 + 1 = 9 2+4+2+1=9 2+4+2+1=9

    2、无权码

    余三码
    余3码是8421 BCD码的每个码组加3(0011)形成的。常用于BCD码的运算电路中。

    十进制0123456789
    二进制(BCD余三码)0011010001010110011110001001101010111100

    实例验证:

    十进制数:7
    二进制数;0111
    2 2 + 2 1 + 2 0 = 4 + 2 + 1 = 7 2^2+2^1+2^0=4+2+1=7 22+21+20=4+2+1=7

    /*二进制加法:逢二进一 */
         0 1 1 1    7
       + 0 0 1 1    3
    
         1 0 1 0   余三码: 7  十进制数:10
    

    余三循环码
    余3循环码是无权码,即每个编码中的1和0没有确切的权值,整个编码直接代表一个数值。主要优点是相邻编码只有一位变化,避免了过渡码产生的“噪声”。

    十进制0123456789
    二进制(BCD余三循环码)0010011001110101010011001101111111101010

    3、BCD运算问题

    我们知道,BCD是用四位二进制数表示十进制数【0~9】的,而四位二进制数可以表示的十进制数为 2 4 = 16 2^4=16 24=16 个即【0~15】,当运算超出范围怎么办?
    解决方案:
    5 + 8 = 13 5+8=13 5+8=13为例
    十进制数: 5 + 8 = 13 5+8=13 5+8=13
    二进制数: 0101 + 1000 = 1101 0101+1000=1101 0101+1000=1101
    差值: 16 − 10 = 6 16-10=6 1610=6
    将所得值加6,产生进位,高位补0
    1101 + 0110 = 00010011 1101+0110=00010011 1101+0110=00010011
    在这里插入图片描述

    /*二进制加法:逢二进一 */
               1 1 0 1    13
             + 0 1 1 0    6
            1  1          产生进位
      0 0 0 1  0 0 1 1    高位补0
    

    二、二进制BCD码

    1、原理实现

    使用逐步移位法来实现二进制数向BCD码的转换;
    变量定义:

    • B:需要转换的二进制数位宽
    • D:转换后的BCD码位宽(其中BCD码的位宽计算如下:根据二进制数的位宽,求出它的无符号数能表示的最大值和最小值,如数据位宽是8位则数据范围大小就是0~255,我们取最大值255,每一个数字对应4位BCD码,三个数字就对应3x4=12位的BCD码)
    • N:需要转换的二进制数位宽加上转换后的BCD码位宽

    逐步移位法的规则:

    • 准备一个N比特的移位寄存器;
    • 二进数逐步左移;
    • 每次左移之后每个BCD位做大四加三的调整;
    • 二进数全部移完,得到结果。

    移位流程表

    移位次数BCD[11:8]BCD[7:4]BCD[3:0]bin[7:0]说明
    010100101输入二进制数
    1101001010左移一位,低位补0
    21010010100左移两位,低位补0
    310100101000101=5;大于4加3
    3100000101000加3不移位
    410000010100001000移位,原始值也移位,低位补0
    510000010100000循环移位,低位补0
    6100000101000000循环移位,低位补0
    71000001010000000循环移位,低位补0
    71011001010000000循环移位,低位补0
    810110010100000000循环移位,低位补0
    BCD165移位结束,输出BCD码

    2、模块划分

    顶层模块
    在这里插入图片描述
    代码实现

    module bin2bcd (
        
        input         [7:0]       bin    ,//二进制输入
        output        [11:0]      bcd     //bcd码输出
    );
    
       //信号定义
       wire        [19:0]         bcd_reg0  ;
       wire        [19:0]         bcd_reg1  ;
       wire        [19:0]         bcd_reg2  ;
       wire        [19:0]         bcd_reg3  ;
       wire        [19:0]         bcd_reg4  ;
       wire        [19:0]         bcd_reg5  ;
       wire        [19:0]         bcd_reg6  ;
       wire        [19:0]         bcd_reg7  ;
       wire        [19:0]         bcd_reg8  ;//八次移位结果输出
    
       assign bcd_reg0 = {12'b0000_0000_0000,bin};//将输入的八位二进制转换为二十位
       //第一次移位
       bcd_modify b1
       (.data_in(bcd_reg0),.data_out(bcd_reg1));
       //第二次移位
       bcd_modify b2
       (.data_in(bcd_reg1),.data_out(bcd_reg2));
       //第三次移位
       bcd_modify b3
       (.data_in(bcd_reg2),.data_out(bcd_reg3));
       //第四次移位
       bcd_modify b4
       (.data_in(bcd_reg3),.data_out(bcd_reg4));
       //第五次移位
       bcd_modify b5
       (.data_in(bcd_reg4),.data_out(bcd_reg5));
       //第六次移位
       bcd_modify b6
       (.data_in(bcd_reg5),.data_out(bcd_reg6));
       //第七次移位
       bcd_modify b7
       (.data_in(bcd_reg6),.data_out(bcd_reg7));
       //第八次移位
       bcd_modify b8
       (.data_in(bcd_reg7),.data_out(bcd_reg8));
       //BCD输出
       assign bcd = {bcd_reg8[19:8]};//取高12位为输出结果
    
    endmodule
    

    移位模块
    在这里插入图片描述
    代码实现

    //移位处理模块
    
    module bcd_modify (
        
        input       [19:0]    data_in ,//移位比较数据输入
        output      [19:0]    data_out //移位比较数据输出
    );
    
        //信号定义
        wire         [3:0]      reg1    ;//移位结果输出
        wire         [3:0]      reg2    ;
        wire         [3:0]      reg3    ;
    
        //左移大4加3比较 [19:16]
        bcd_cmp c1
        (.cmp_in(data_in[19:16]),.cmp_out(reg1));
        //左移大4加3比较 [15:12]
        bcd_cmp c2
        (.cmp_in(data_in[15:12]),.cmp_out(reg2));
        //左移大4加3比较 [11:8]
        bcd_cmp c3
        (.cmp_in(data_in[11:8]),.cmp_out(reg3));
        //比较完成 左移一位
        assign data_out = {reg1[2:0],reg2,reg3,data_in[7:0],1'b0};
        
    endmodule
    

    大四加三处理模块
    在这里插入图片描述
    代码实现

    //大四加三处理
    module bcd_cmp(
    
        input      [3:0]    cmp_in  ,//比较器数据输入
        output  reg[3:0]    cmp_out  //比较器数据输出
    );
       
       always @(*) begin
           if(cmp_in > 4)
           cmp_out = cmp_in + 3;//大于四加三
           else
           cmp_out = cmp_in;//小或等于四 不作处理
       end
    
    endmodule
    

    3、仿真调试

    仿真文件【testbench】

    `timescale 1ns/1ps
    module bin2bcd_tb();
    reg        [7:0]     bin   ;
    wire       [11:0]    bcd   ;
    bin2bcd u_bin2bcd
    (
        .bin         ( bin   ),
        .bcd         ( bcd   )
    );
    parameter CYCLE = 20;
    initial begin
        #(CYCLE*200);
        bin = 8'b0;//bin信号初始化
        #(CYCLE*100);
        bin = 8'b1010_1101;//173
        #(CYCLE*100);
        bin = 8'b0000_1101;//13
        #(CYCLE*100);
        bin = 8'b1010_0100;//164
        #(CYCLE*100);
        bin = 8'b1000_0000;//128
        #(CYCLE*100);
        bin = 8'b1111_1111;//255
        $stop;
    end
    endmodule
    

    【do】文件

    vlib work
    vmap work work
    #编译testbench文件
    vlog  bin2bcd_tb.v
    #编译设计文件
    vlog ../rtl/bcd_cmp.v
    vlog ../rtl/bin2bcd.v
    vlog ../rtl/bcd_modify.v
    #指定仿真顶层
    vsim -novopt work.bin2bcd_tb
    #添加信号到波形窗
    add wave -position insertpoint sim:/bin2bcd_tb//*
    

    do调试流程
    打开仿真调试工具modelsim
    在这里插入图片描述
    点击【file】->【change Directory…】
    在这里插入图片描述
    找到tb文件【或者仿真测试文件还有do文件所在目录】
    在这里插入图片描述
    左下角查看打开的目录
    在这里插入图片描述
    使用指令,开始仿真【do do.do】;然后回车

    do filename.do
    

    在这里插入图片描述
    编译无报错【注意错误和警告信息】
    在这里插入图片描述

    4、仿真验证

    将bin用十进制表示,加上【unsigned】
    在这里插入图片描述

     #(CYCLE*200);
        bin = 8'b0;//bin信号初始化
        #(CYCLE*100);
        bin = 8'b1010_1101;//173
        #(CYCLE*100);
        bin = 8'b0000_1101;//13
        #(CYCLE*100);
        bin = 8'b1010_0100;//164
        #(CYCLE*100);
        bin = 8'b1000_0000;//128
        #(CYCLE*100);
        bin = 8'b1111_1111;//255
    

    对比可以发现,输入值符合预期。
    下面任意取一个值进行验证。

    十进制数:128
    BCD码表示:0001 0010 1000

    取BCD输出的高12位为输出结果【输入为8,低位为移位补0值】
    在这里插入图片描述
    经过对比,输出与实际值吻合。

    三、BCD码转二进制

    1、原理实现

    移位算法原理
    二进制码左移一位等于未左移的二进制码*2,例如有二进制码101001,转成十进制等于41,左移一位得到1010010,转成十进制等于82。也就是说二进制码左移1位加上左移3位可以等效于二进制码乘以10。

    2、模块划分

    移位相加
    在这里插入图片描述
    代码实现

    /************************工程说明*********************
       BCD码转二进制码
    *****************************************************/
    module bcd2bin(
    
        input                 clk      ,//系统时钟 50Mhz
        input                 rst_n    ,//复位 低电平有效
        input        [3:0]    bw       ,//BCD码百位
        input        [3:0]    sw       ,//BCD码十位
        input        [3:0]    gw       ,//BCD码个位
        output       [9:0]    bin       //二进制输出
    );
    
       //信号定义
       reg           [9:0]    bw_v1   ;//BCD码百位寄存器1
       reg           [9:0]    bw_v2   ;//BCD码百位寄存器2
       reg           [9:0]    bw_v3   ;//BCD码百位寄存器3
       reg           [9:0]    sw_v1   ;//BCD码十位寄存器1
       reg           [9:0]    sw_v2   ;//BCD码十位寄存器2
       reg           [9:0]    gw_v1   ;//BCD码个位寄存器
    
       /**********************换算规则:**********************
       BCD百位:a*100=a*(64+32+4)=a*64+a*32+a*4 =a000000+a00000+a00,即a左移6位加上左移5位加上a左移2位 
       BCD十位:a*10=a*(8+2)=a*8+a*2 =a000+a0,即a左移3位加上左移1位     
       BCD个位:个位数据不变
       将所有的各个位的转换结果相加就是转换后的二进制数
       左移运算:2^n      右移运算:1/(2^n)
       ******************************************************/
       //寄存器赋初值
       always @(posedge clk or negedge rst_n) begin
           if(!rst_n)begin
             bw_v1 <= 0;
             bw_v2 <= 0;
             bw_v3 <= 0;
             sw_v1 <= 0;
             sw_v2 <= 0;
             gw_v1 <= 0;
           end
           else begin
             bw_v1 <= bw << 6;//左移六位
             bw_v2 <= bw << 5;//左移五位
             bw_v3 <= bw << 2;//左移两位
             sw_v1 <= sw << 3;//左移三位
             sw_v2 <= sw << 1;//左移一位
             gw_v1 <= gw;//个位保持不变
           end
       end
       assign bin = bw_v1 + bw_v2 + bw_v3 + sw_v1 + sw_v2 + gw_v1;
    
    endmodule
    

    3、仿真验证

    仿真测试文件【testbench】

    //时间单位/精度
    `timescale 1ns/1ps
    
    module bcd2bin_tb();
    //激励信号
    reg                        clk    ;
    reg                        rst_n  ;
    reg            [3:0]       bw     ;
    reg            [3:0]       sw     ;
    reg            [3:0]       gw     ;
    //输出信号
    wire           [9:0]       bin    ;
    
    //模块例化
    bcd2bin    u_bcd2bin
    (
        .clk       ( clk    ),
        .rst_n     ( rst_n  ),
        .bw        ( bw     ),
        .gw        ( gw     ),
        .sw        ( sw     ),
        .bin       ( bin    )
    );
    
    //产生时钟
    parameter CYCLE = 20;
     
     always #(CYCLE/2) clk = ~clk;
      
      //产生激励
      initial begin
          clk   = 1'b0;
          rst_n = 1'b0;
          bw = 4'd0; sw = 4'd0; gw = 4'd0;//000
          #(CYCLE*500);
          rst_n = 1'b1;
          #(CYCLE*1000);
          bw = 4'd1; sw = 4'd2; gw = 4'd0;//120
          #(CYCLE*1000);
          bw = 4'd3; sw = 4'd2; gw = 4'd9;//329
          #(CYCLE*1000);
          bw = 4'd7; sw = 4'd0; gw = 4'd3;//703
          #(CYCLE*1000);
          bw = 4'd0; sw = 4'd2; gw = 4'd7;//027
          #(CYCLE*1000);
          bw = 4'd2; sw = 4'd9; gw = 4'd0;//290
          #(CYCLE*5000);
          $stop;
    
      end
    
    endmodule
    

    do文件

    vlib work
    vmap work work
    
    #编译testbench文件
    vlog bcd2bin_tb.v
    
    #编译设计文件 
    vlog ../rtl/bcd2bin.v
    
    #指定仿真顶层
    vsim -novopt work.bcd2bin_tb
    
    #添加信号到波形窗
    add wave -position insertpoint sim:/bcd2bin_tb//*
    

    验证结果
    输入值查看
    在这里插入图片描述
    仿真输入值

    bw = 4'd0; sw = 4'd0; gw = 4'd0;//000
          #(CYCLE*500);
          rst_n = 1'b1;
          #(CYCLE*1000);
          bw = 4'd1; sw = 4'd2; gw = 4'd0;//120
          #(CYCLE*1000);
          bw = 4'd3; sw = 4'd2; gw = 4'd9;//329
          #(CYCLE*1000);
          bw = 4'd7; sw = 4'd0; gw = 4'd3;//703
          #(CYCLE*1000);
          bw = 4'd0; sw = 4'd2; gw = 4'd7;//027
          #(CYCLE*1000);
          bw = 4'd2; sw = 4'd9; gw = 4'd0;//290
          #(CYCLE*5000);
    

    输出结果

    百位:左移六位+左移五位+左移两位
    十位:左移三位+左移一位
    个位:不变

    在这里插入图片描述
    经对比,结果符合预期。

    展开全文
  • verilog 二进制BCD

    千次阅读 热门讨论 2021-04-02 17:46:34
    每一次移位之后都判断下,BCD码计数器的十、分以及个位是否大于4,如果任何一位(4bit)大于4,则对其加3,之后继续移位,如此下去,直到移位次数为二进制数的位数之后,停止移位,此时得到的BCD码计数值便是转换后...

    1、计算过程
    先将BCD码计数器清零,之后将二进制数和BCD码计数器统统左移,二进制数移出来的最高位放到BCD码计数器的最低位,如下表所示!
    在这里插入图片描述
    每一次移位之后都判断下,BCD码计数器的十、分以及个位是否大于4,如果任何一位(4bit)大于4,则对其加3,之后继续移位,如此下去,直到移位次数为二进制数的位数之后,停止移位,此时得到的BCD码计数值便是转换后的值。

    2、实现

    module bin2bcd(
        input clk,
        input rst_n,
        input en,
        input [7:0] data_bin,
        output reg [11:0] data_bcd,
        output reg data_bcd_valid
        );
        
    reg [2:0] state, next_state;
    reg [3:0] num;
    reg flag;
    reg [11:0] bcd_buf;
    reg  [7:0] data_bin_reg;
    parameter IDLE = 3'd1;
    parameter SHIFT = 3'd2;
    parameter JUDGE = 3'd3;
    parameter ADD = 3'd4;
    parameter DONE = 3'd5;
    reg [1:0] wait_cnt;
    
    always@(posedge clk or negedge rst_n)begin
        if(~rst_n)begin
            bcd_buf <= 12'd0; 
            data_bcd <= 12'd0;
            state <= IDLE;
            num <= 4'd0;
            data_bcd_valid <= 0;
        end
        else begin
            case(state)
                IDLE:begin
                    num <= 4'd0;
                    data_bcd_valid <= 0;
                    data_bin_reg <= data_bin ;
                    bcd_buf <= 12'd0; 
                    data_bcd <= 12'd0;
                    if(en)
                        state <= SHIFT;
                    else
                        state <= IDLE;
                end
                SHIFT:begin
                    bcd_buf <= bcd_buf << 1;
                    data_bin_reg <= data_bin_reg << 1;
                    bcd_buf[0] <= data_bin_reg[7];
                    num <= num + 4'd1;
                    if(num == 4'd7)begin
                        state <= DONE;
                    end
                    else 
                        state <= JUDGE;
                end
                JUDGE:begin
                    if(bcd_buf[11:8]>4 || bcd_buf[7:4]>4 || bcd_buf[3:0]>4)
                        state <=  ADD;
                    else 
                        state <= SHIFT;
                end
                ADD:begin
                    if(bcd_buf[11:8]>4)
                        bcd_buf[11:8] <= bcd_buf[11:8] + 4'd3;
                    if(bcd_buf[7:4]>4)
                        bcd_buf[7:4] <= bcd_buf[7:4] + 4'd3;
                    if(bcd_buf[3:0]>4)
                        bcd_buf[3:0] <= bcd_buf[3:0] + 4'd3;
                    state <= SHIFT;            
                end
                DONE:begin
                   state <=  IDLE;   
                   data_bcd <= bcd_buf; 
                   data_bcd_valid <= 1'd1;       
                end
                default:begin
                    bcd_buf <= bcd_buf; 
                    data_bcd <= data_bcd; 
                    data_bcd_valid <= 1'd0;
                    state <= IDLE;
                    num <= 3'd0;
                end
            endcase
        end
    end
    endmodule
    

    3、验证

    module bcd_tb(
    
        );
    reg clk;
    reg rst_n;
    reg en;
    reg [7:0] data_bin;
    wire [11:0] data_bcd;
    
    
    always #50 clk = ~clk;
    initial begin
        clk = 1;
        rst_n = 0;
        en = 0;
        data_bin = 8'd0;
        #200;
        en = 1;
        rst_n = 1;
        data_bin = 8'b11110011;
        #200000;
        $stop;
    end
    
        
    bin2bcd u_bin2bcd(
        .clk      (clk     ) ,
        .rst_n    (rst_n   ) ,
        .en       (en      ) ,
        .data_bin (data_bin) ,
        .data_bcd (data_bcd)
        );
    endmodule
    

    在这里插入图片描述
    以下是参考别人用于对比的数据,结果能对应上
    在这里插入图片描述

    展开全文
  • FPGA零基础学习:基于FPGA的二进制BCD设计(附代码) 本系列将带来FPGA的系统性学习,从最基本的数字电路基础开始,最详细操作步骤,最直白的言语描述,手把手的“傻瓜式”讲解,让电子、信息、通信类专业学生、...
  • FPGA Verilog实现二进制BCD

    千次阅读 2021-07-16 19:14:01
    二进制BCD码可以采用Double_dabble算法,维基百科有详细介绍,简单可称为“移位加3”算法。 8位二进制数243,移位加3计算过程: 16位二进制65244,移位加3计算过程: verilog实现 方法1:纯组合逻辑实现 来自...
  • 二进制转8421BCD码的算法

    千次阅读 2021-05-20 12:35:15
    1. BCD码的求和BCD码使用4位二进制数来表示十进制中0~9这10个数的数码。例如,十进制的237,其BCD码就是0010_0011_0111,但是其二进制是1110_1101。我们先来研究两个4位的BCD码相加的情况。设这两个BCD码对应的十...
  • 常见的进位数制有:二进制(Binary)、十进制(Decimal)和十六进制(Hexadecimal)。人类的思维习惯于十进制(Decimal),所谓“逢十进一”。这个没什么好说的,地球人都知道。本文要介绍的是PLC编程相关的...
  • 如果你收到的数据为二进制,比如00010101 为十进制21,要转化成ASCII类型或者BCD码,为00100001 / 32 31 下面算法很好的解决 可以。
  • BCD 码(Binary-Coded Decimal),又称二 - 十进制码,使用 4 位二进制数来表示 1 位十进制数中的 0~9 这 10 个数码,是一种二进制的数字编码形式,用二进制编码的十进制代码。
  • BCD码怎么转换成标准二进制形式?

    千次阅读 2021-05-25 04:14:00
    满意答案tcpc182014.11.18采纳率:53%等级:9已帮助:165人二进制编码的十进制数,简称BCD码(BinarycodedDecimal).这种方法是用4位二进制码的组合代表十进制数的0,1,2,3,4,5,6,7,8,9十个数符。4位二进制...
  • 8421bcd转换二进制

    千次阅读 2021-07-23 03:24:56
    8421BCD码进制也就是进制位,对于接触过电脑的人来说应该都不陌生,我们常用的进制包括:二进制、八进制、十进制与十六进制,它们之间区别在于数运算时是逢几进一位。最右侧数字是错误类型,2位,16进制,含义仍未知...
  • bcd二进制转十进制Prerequisite: Number systems 先决条件: 数字系统 BCD Code (8421 Code): In BCD 8421 code, each decimal digit is represented using a 4-bit binary number. The 4-bit binary numbers ...
  • C语言:十进制BCD码互换

    万次阅读 2021-08-30 16:38:17
    最近写单片机 RTC 日期、时间配置,需要实现十进制BCD码互换,将示例Demo分享给各位朋友~
  • 1,转换为整数进行计算。 2,采用BCD(Binary Coded Decimal)方法。 3,想办法忽略,如计算时不用==,而用相减<0.00001,符号进行大小判断。 总之,整数计算是不会出错的 总之,数字是可以变换的,整数小数可以...
  • 转换BCD码,也就是将顺序编码的二进制数字的个位、十位、百位等计算出来,用四位二进制表示,组合到一起就是BCD码。 将一个数字对10求余将得到个位。 将一个数字减去个位后,除以10,然后在对10求余将得到十位。...
  • BCD码这种编码形式利用了四个位元来储存一个十进制的数码,使二进制和十进制之间的转换得以快捷的进行。 3. 实现方法 1) 对10求余法 将需要转换的数字除以“权”,然后对10求余,得出数字各个位上的数字。例如:8...
  • 1、第二章:数据的表示和运算通过下面的思维导图来依次分享「数据的表示和运算」里面重要知识点。2、第一节:数制与编码1....3. BCD码:二进制的十进制数(Binary-coded Decimal,BCD)通常采用4位二进...
  • FPGA 二进制bcd

    千次阅读 2018-10-28 19:15:47
    //这是一个使用Verilog HDL编写的带使能端的8-bit二进制BCD码... //rst_n为使能端,binary为待转换二进制数,bcd转换后的BCD码 parameter B_SIZE=12; //B_SIZE为二进制数所占的位数,可根据需要进行扩展...
  • BCD码的学习以及进制之间的换算
  • 进制BCD转换的算法

    万次阅读 多人点赞 2018-08-06 13:13:47
    BCD是指用二进制来表示十进制数的编码,即用4位二进制来表示一位十进制数,因此4位二进制数表示最大的十进制数9(1001),只取十六个数中的十个数。 比如: BCD码:0x99(153),该BCD转换成十进制是99. 算法...
  • 在做而论道上篇博文中,回答了一个16位二进制转换BCD码的问题,给出了一个网上广泛流传的经典转换程序。.说它经典,不仅是因为它已经流传已久,重要的是它的编程思路十分清晰,十分易于延伸推广。做而论道曾经...
  • BCD码转二进制的原理
  • 什么是 BCD二进制编码的十进制)

    千次阅读 2022-01-01 11:30:06
    BCD 是一位十进制数,由代表 0 到 9 的四位二进制数字表示。 当寄存器值以十六进制表示时,可以原样读取为十进制数,这对于处理十进制数的函数来说非常方便。 二进制数的 4 位可以表示为 0 到 15,但只有低 10 位被...
  • java二进制,字节数组,字符,十六进制,BCD编码转换java中byte用二进制表示占用8位,而我们知道16进制的每个字符需要用4位二进制位来表示(23 + 22 + 21 + 20 = 15),所以我们就可以把每个byte转换成两个相应的16进制...
  • 格雷码自然二进制码相邻数据之间可能存在多个bit的变化,例如自然数7和8对应的4bits自然二进制码分别“0111”、“1000的输出从7变到8时,寄存器的每一位都会发生变化,从而造成不稳定态,并且会使得数字电路产生很大...
  • 、实验内容 1、完成单片机开发相关必备软件的安装 2、学习单片机开发板套件的实验原理图 3、编写、下载及实现第一个单片机程序(点亮一个LED灯) 三、实验原理 单片机开发板原理图;单片机并行输入输出接口 四、...
  • 在分析代码之前,我们先来了解一下,BCD码和二进制到底区别在哪?  学习过计算机原理的和数字电子技术这两门课的都会知道这两个到底是什么含义,也有的同学学过了,考过了,过了一段时间又忘记了,今天,我们通过一...
  •  8bit位宽二进制小数:(0.a1a2a3a4a5a6a7a8)2(0.a_1 a_2 a_3 a_4 a_5 a_6 a_7 a_8)_2(0.a1​a2​a3​a4​a5​a6​a7​a8​)2​  8位小数BCD码表示为:(0.b1b2b3b4b5b6b7b8)2(0.b_1 b_2 b_3 b_4 b_5 b_6 b_7 b_8)_2...
  • 进制转换BCD

    千次阅读 2021-07-05 21:30:18
    4合闸命令 // 控制字©:1C // 数据帧:68 01 00 00 00 00 00 68 1C 10 35 33 33 33 44 44 44 44 4E 33 45 // C# BCD码与十进制数的转换 // BCD码(Binary-Coded Decimal)是二进制编码的十进制数的缩写,BCD码用4位2进制...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 8,427
精华内容 3,370
热门标签
关键字:

二进制转换bcd计算