wuyongduoduo 发表于 2016-8-23 08:40:25

锦夏笔记(三)十进制转 bcd码

本帖最后由 wuyongduoduo 于 2016-8-23 08:40 编辑

      今天是进行矩阵键盘计算器项目的第3天,主要任务是设计十进制数转换成BCD码模块,该模块属于数码管模块,模块名称为smg_bcd。
      将十进制数转换成BCD码有多种方法,其中一种方法如下:将十进制数a对10取余(a%10),即可得到个位;将a整除10后再对10取余((a/10)%10),即可得到十位;以此类推即可得到各位上的数。但由于除法器电路非常庞大,耗费资源且延迟较大,影响整个电路的运行,一般不采用这种方法。
      今天设计的转BCD码用了一种算法,具体如下:
      
      上图举了一个例子,将十进制数255转化成BCD码。首先将十进制数转换成了8位二进制数格式(系统自动就能转换,不需另外进行),自左至右排列以下数据:待转换的数据、BCD码的个位(4位二进制数)、BCD码的十位(4位二进制数)、BCD码的百位(4位二进制数)。然后将上述数据一位一位地向左移动,每移动一位就判断一下BCD码的个位、十位、百位是否大于或者等于5,是则加3后左移,否则继续左移,直至将8位待转换的数据全部左移完成。
      我们所用的开发板上共有6个数码管,最大可显示的十进制数是999999,转换成二进制数是1111_0100_0010_0011_1111(20位)。定义一个20位的变量bcd_num_r0来存放待转换的十进制数,再定义6个4位的变量bcd_num_r1~ bcd_num_r6来作为上图中BCD码的各个位(个位、十位、百位等),还需定义一个24位的变量来存放最终转换完成的bcd码bcd_num_r,然后按照上面例子的算法进行转换,主要代码如下:
case(bcd_state)
                                IDLE: begin /**************各变量在空闲状态要清零,若不清零容易导致第二次进行转码时出现错误**********************/
                                                        bcd_num_r0 <= dec_num;                                                       
                                                        bcd_num_r6 <= 4'd0;
                                                        bcd_num_r5 <= 4'd0;                               
                                                        bcd_num_r4 <= 4'd0;
                                                        bcd_num_r3 <= 4'd0;
                                                        bcd_num_r2 <= 4'd0;
                                                        bcd_num_r1 <= 4'd0;
                                                        bcd_state <= LEFT;
                                                end
                                LEFT: begin/****************8将bcd_num_r6~r0中的数据左移*************************/
                                                        bcd_num_r6 <= {bcd_num_r6,bcd_num_r5};
                                                        bcd_num_r5 <= {bcd_num_r5,bcd_num_r4};
                                                        bcd_num_r4 <= {bcd_num_r4,bcd_num_r3};
                                                        bcd_num_r3 <= {bcd_num_r3,bcd_num_r2};
                                                        bcd_num_r2 <= {bcd_num_r2,bcd_num_r1};
                                                        bcd_num_r1 <= {bcd_num_r1,bcd_num_r0};
                                                        bcd_num_r0 <= {bcd_num_r0,1'b0};
                                                        if(cnt >= 19)
                                                                begin               
                                                                        cnt <= 0;
                                                                        bcd_state <= END;/***************左移(19+1)次后完成移动跳转至END状态**********************/
                                                                end
                                                        else
                                                                begin
                                                                        bcd_state <= ADD;/****************若未完成移动则跳转至ADD状态**************************/
                                                                        cnt <= cnt + 1'b1;
                                                                end
                                                end
                                ADD:begin        /************************************判断bcd_num_r1~r6中的数据是否需要加3**********************************/                                               
                                                        if(bcd_num_r6 >= 5)
                                                                begin
                                                                        bcd_num_r6 <= bcd_num_r6 + 4'd3;
                                                                        bcd_state <= LEFT;
                                                                end
                                                        else
                                                                begin
                                                                        bcd_num_r6 <= bcd_num_r6;
                                                                        bcd_state <= LEFT;
                                                                end
                                                        if(bcd_num_r5 >= 5)
                                                                begin
                                                                        bcd_num_r5 <= bcd_num_r5 + 4'd3;
                                                                        bcd_state <= LEFT;
                                                                end
                                                        else
                                                                begin
                                                                        bcd_num_r5 <= bcd_num_r5;
                                                                        bcd_state <= LEFT;
                                                                end
                                                        if(bcd_num_r4 >= 5)
                                                                begin
                                                                        bcd_num_r4 <= bcd_num_r4 + 4'd3;
                                                                        bcd_state <= LEFT;
                                                                end
                                                        else
                                                                begin
                                                                        bcd_num_r4 <= bcd_num_r4;
                                                                        bcd_state <= LEFT;
                                                                end
                                                        if(bcd_num_r3 >= 5)
                                                                begin
                                                                        bcd_num_r3 <= bcd_num_r3 + 4'd3;
                                                                        bcd_state <= LEFT;
                                                                end
                                                        else
                                                                begin
                                                                        bcd_num_r3 <= bcd_num_r3;
                                                                        bcd_state <= LEFT;
                                                                end
                                                        if(bcd_num_r2 >= 5)
                                                                begin
                                                                        bcd_num_r2 <= bcd_num_r2 + 4'd3;
                                                                        bcd_state <= LEFT;
                                                                end
                                                        else
                                                                begin
                                                                        bcd_num_r2 <= bcd_num_r2;
                                                                        bcd_state <= LEFT;
                                                                end
                                                        if(bcd_num_r1 >= 5)
                                                                begin
                                                                        bcd_num_r1 <= bcd_num_r1 + 4'd3;
                                                                        bcd_state <= LEFT;
                                                                end
                                                        else
                                                                begin
                                                                        bcd_num_r1 <= bcd_num_r1;
                                                                        bcd_state <= LEFT;
                                                                end
                                           end
                                END:begin /********************转码成功,输出bcd_num_r********************************8/
                                                        bcd_num_r <= {bcd_num_r6,bcd_num_r5,bcd_num_r4,
                                                                                        bcd_num_r3,bcd_num_r2,bcd_num_r1};
                                                        bcd_state <= IDLE;
                                                end
                                default: bcd_state <= IDLE;
                                endcase
assign bcd_num = bcd_num_r;

Blondie 发表于 2016-8-23 09:21:03

                        感谢楼主分享

芙蓉王 发表于 2016-8-23 09:26:15

                        感谢分享

Esmiamor 发表于 2016-8-23 09:35:19

                  不错,坚持。
页: [1]
查看完整版本: 锦夏笔记(三)十进制转 bcd码