数码管动态显示(二)——BCD码转码


前言

提示:这里可以添加本文要记录的大概内容:

BCD码(Binary-Coded Decimal),又称二-十进制码,使用4位二进制数来表示1位十进制数中的0~9这10个数码,是一种二进制的数字编码形式,用二进制编码的十进制代码。
分为有权码(8421 5421 2421码)和无权码(余3码和格雷码)。
在这里插入图片描述有权码计算方式:权重和编码数字之积的和为十进制数。
例:十进制234=1110-1010(二进制)=0010-0011-0100(8421码)
使用BCD码的原因:数码管显示234,先显示个位,再显示十位,后显示百位,BCD码可以识别个十百位。


提示:以下是本篇文章正文内容,下面案例可供参考

一、更新系统框图

在这里插入图片描述bcd子模块左侧为待显示data数据(最大值999_999),右侧为个十百千万 十万位。


二、波形图

1.设置最大值为987654(对应二进制为1111 0001 0010 0000 0110),data的位宽为20位。
2.设置一个移位记数器,8位二进制转换为BCD码需要左移8次,20位左移20次(对应二进制0001 0100),移位器位宽为5位。声明:需要增加两个状态:还未左移的最初状态和输出结果(提取转化完成的BCD码),故记数0-21共22次。
3.移位产生的中间数据需要寄存,声明一个data_shift寄存器,其位宽为20位二进制码+24位(6*4)BCD码,位宽为44位。
4.判断信号(是否>4)在前,移位在后,还需要设置一个标志信号区分这两个操作,也可以看作移位次数记数的条件。
当移位标志信号为低电平时进行判断运算,计数器保持不变,为高电平时进行移位,计数器进行记数。
在这里插入图片描述在这里插入图片描述


三、rtl代码和测试代码

module  bcd
(
    input   wire            sys_clk     ,   //系统时钟,频率50MHz
    input   wire            sys_rst_n   ,   //复位信号,低电平有效
    input   wire    [19:0]  data        ,   //输入需要转换的数据

    output  reg     [3:0]   unit        ,   //个位BCD码
    output  reg     [3:0]   ten         ,   //十位BCD码
    output  reg     [3:0]   hun         ,   //百位BCD码
    output  reg     [3:0]   tho         ,   //千位BCD码
    output  reg     [3:0]   t_tho       ,   //万位BCD码
    output  reg     [3:0]   h_hun           //十万位BCD码
);

reg     [4:0]   cnt_shift   ;   //移位判断计数器
reg     [43:0]  data_shift  ;   //移位判断数据寄存器
reg             shift_flag  ;   //移位判断标志信号

//cnt_shift:从0到21循环计数
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        cnt_shift   <=  5'd0;
    else    if((cnt_shift == 5'd21) && (shift_flag == 1'b1))
        cnt_shift   <=  5'd0;
    else    if(shift_flag == 1'b1)
        cnt_shift   <=  cnt_shift + 1'b1;
    else
        cnt_shift   <=  cnt_shift;//低电平保持不变
        
//data_shift:计数器为0时赋初值,计数器为1~20时进行移位判断操作
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        data_shift  <=  44'b0;
    else    if(cnt_shift == 5'd0)
        data_shift  <=  {24'b0,data};
    else    if((cnt_shift <= 20) && (shift_flag == 1'b0))
        begin
            data_shift[23:20]   <=  (data_shift[23:20] > 4) ? (data_shift[23:20] + 2'd3) : (data_shift[23:20]);
            data_shift[27:24]   <=  (data_shift[27:24] > 4) ? (data_shift[27:24] + 2'd3) : (data_shift[27:24]);
            data_shift[31:28]   <=  (data_shift[31:28] > 4) ? (data_shift[31:28] + 2'd3) : (data_shift[31:28]);
            data_shift[35:32]   <=  (data_shift[35:32] > 4) ? (data_shift[35:32] + 2'd3) : (data_shift[35:32]);
            data_shift[39:36]   <=  (data_shift[39:36] > 4) ? (data_shift[39:36] + 2'd3) : (data_shift[39:36]);
            data_shift[43:40]   <=  (data_shift[43:40] > 4) ? (data_shift[43:40] + 2'd3) : (data_shift[43:40]);
        end
    else    if((cnt_shift <= 20) && (shift_flag == 1'b1))
        data_shift  <=  data_shift << 1;
    else
        data_shift  <=  data_shift;
        
//shift_flag:移位判断标志信号,用于控制移位判断的先后顺序
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        shift_flag  <=  1'b0;
    else
        shift_flag  <=  ~shift_flag;
        
//当计数器等于20时,移位判断操作完成,对各个位数的BCD码进行赋值
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        begin
            unit    <=  4'b0;
            ten     <=  4'b0;
            hun     <=  4'b0;
            tho     <=  4'b0;
            t_tho   <=  4'b0;
            h_hun   <=  4'b0;
        end
    else    if(cnt_shift == 5'd21)
        begin
            unit    <=  data_shift[23:20];
            ten     <=  data_shift[27:24];
            hun     <=  data_shift[31:28];
            tho     <=  data_shift[35:32];
            t_tho   <=  data_shift[39:36];
            h_hun   <=  data_shift[43:40];
        end

endmodule
`timescale  1ns/1ns
module  tb_bcd();

reg     sys_clk     ;
reg     sys_rst_n   ;
reg     [19:0]  data;

wire     [3:0]   unit        ;
wire     [3:0]   ten         ;
wire     [3:0]   hun         ;
wire     [3:0]   tho         ;
wire     [3:0]   t_tho       ;
wire     [3:0]   h_hun       ;

initial
    begin
        sys_clk     =   1'b1;
        sys_rst_n   <=  1'b0;
//生成模拟数据
        data<=20'd0;
        #30
        sys_rst_n   <=  1'b1;
        data<=20'd123_456;
        #3000
        data<=20'd654_321;
        #3000
        data<=20'd987_654;
        #3000
        data<=20'd999_999;
    end
    
bcd bcd_inst
(    
    .sys_clk   (sys_clk   )  ,
    .sys_rst_n (sys_rst_n )  ,
    .data      (data      )  ,
    .unit  (unit ),
    .ten   (ten  ),
    .hun   (hun  ),
    .tho   (tho  ),
    .t_tho (t_tho),
    .h_hun (h_hun)
);

endmodule    
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小年痴槑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值