设为首页 加入收藏

TOP

基于Verilog HDL的二进制转BCD码实现(一)
2019-08-24 00:06:50 】 浏览:48
Tags:基于 Verilog HDL 二进制 BCD 实现

       在项目设计中,经常需要显示一些数值,比如温湿度,时间等等。在数字电路中数据都是用二进制的形式存储,要想显示就需要进行转换,对于一个两位的数值,对10取除可以得到其十位的数值,对10取余可以得到个位的数值。对于Verilog来说它的标准是支持除法和取余运算的,综合器也会有IP可以进行除法运算。但是这样未免会耗费太多资源,使用移位加3算法就可以实现二进制到BCD码之间的转换。

       BCD码(Binary-Coded Decimal?)亦称二进码十进数或二-十进制代码。用4位二进制数来表示1位十进制数中的0~9这10个数码。

       移位加3算法简单来说就是,有多少位二进制说,就进行多少次移位,以八位的二进制为例,其数值最高可为三位十进制数,进行如下表左移,在移位的过程中,如果移位出的数值大于4,则将改为的数值加3后再进行移位。

这里为什么大于四,BCD码是四位二进制数表示一个十进制数的一位,如果这以为大于4,比如5,4’b0101,下一次移位后变成了4’b1010,BCD码中是没有4’b1010的,所以要加6,向高位进位。这里就是移位后加6和移位前加3,两种方法修正,我这里选择了移位前加3。(4’b0011左移后也是4’b0110,移位前和移位后都是一样的对BCD码的位数进行修正)。

为什么用左移的方法呢?这是因为二进制数和十进制数之间的位权的关系。所以二进数和十进制数之间的转化是乘以2,也就是左移一位。转换公式大概就是这个样子。

公式编辑采用Markdown编辑器Typora完成,Typora支持LaTex语法,编写公式真是爽。

       代码实现起来不是很复杂,博主在网上搜索到有些代码使用纯组合逻辑实现的,用了一个for循环,我个人认为这种写法不是很好,所以自己用状态机写了一个。模块设计如下,tran_en是转换使能信号,可以使电平使能也可以是脉冲使能,作为脉冲使能使用的时候,需要在数据来临之后的一个时钟周期给出使能(我的模块是这样的特点),电平使能有效时,需要18个时钟周期完成转换,输入二进制位16bit,输出为四组千百十个位。转换完成后输出一个转换完成标志tran_done。

 

       内部的时序我采用了三段式状态机来完成。IDLE状态接收到使能信号,调到移位状态,经过16次移位。在shift_cnt为17时(这里是因为我状态机的原理所以shift_cnt会计数到17,但移位次数为16),数据转换完成。跳到DONE状态,输出转换完成标志。

 

       采用组合逻辑来实现,移位后的数据值的判断,大于4加3后再进行移位。最后将转换完成后的结果输出。

代码如下:

  1 `timescale      1ns/1ps
  2 // *********************************************************************************
  3 // Project Name :       
  4 // Author       : NingHeChuan
  5 // Email        : ninghechuan@foxmail.com
  6 // Blogs        : http://www.cnblogs.com/ninghechuan/
  7 // File Name    : Bin_BCD.v
  8 // Module Name  :
  9 // Called By    :
 10 // Abstract     :
 11 //
 12 // CopyRight(c) 2018, NingHeChuan Studio.. 
 13 // All Rights Reserved
 14 //
 15 // *********************************************************************************
 16 // Modification History:
 17 // Date         By              Version                 Change Description
 18 // -----------------------------------------------------------------------
 19 // 2018/8/12    NingHeChuan       1.0                     Original
 20 //  
 21 // *********************************************************************************
 22 
 23 module Bin_BCD
 24 #(
 25     parameter       DATA_WIDTH  =   16,
 26     parameter       SHIFT_WIDTH =   5,
 27     parameter       SHIFT_DEPTH =   16
 28     
 29 )
 30 (
 31     input               clk,
 32     input               rst_n,
 33     input               tran_en,
 34     input       [DATA_WIDTH - 1:0]  data_in,
 35     output   reg        tran_done,
 36     output      [3:0]   thou_data,      //千位
 37     output        [3:0]    hund_data,      //百位
 38     output        [3:0]    tens_data,      //十位
 39     output        [3:0]    unit_data       //个位
 40 
 41 );
 42 //-------------------------------------------------------
 43 localparam  IDLE    =   3'b001;
 44 localparam   SHIFT   =   3'b010;
 45 localparam   DONE    =   3'b100;
 46 
 47 //-------------------------------------------------------
 48 reg     [2:0]   pre_state;
 49 reg     [2:0]   next_state;
 50 //
 51 reg     [SHIFT_DEPTH-1:0]   shift_cnt;
 52 //
 53 reg     [DATA_WIDTH:0]  data_reg;
 54 reg     [3:0]   thou_reg;
 55 reg        [3:0]    hund_reg;
 56 reg        [3:0]    tens_reg;
 57 reg        [3:0]    unit_reg; 
 58 reg     [3:0]   thou_out;
 59 reg        [3:0]    hund_out;
 60 reg        [3:0]    tens_out;
 61 reg        [3:0]    unit_out; 
 62 wire    [3:0]   thou_tmp;
 63 wire    [3:0]    hund_tmp;
 64 wire    [3:0]    tens_tmp;
 65 wire    [3:0]    unit_tmp;
 66 
 67 //--------------------------------  
		
基于Verilog HDL的二进制转BCD码实现(一) https://www.cppentry.com/bencandy.php?fid=92&id=230565

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇目标反射回波检测算法及其FPGA实.. 下一篇FPGA中ROM与RAM相关知识总结(五)