利用verilog将二进制码转换为十进制BCD码

小序:

               先说一个 bear 的亲身体会,bear 在做一些 fpga 小设计时经常会用到数据显示功能,比如数字时钟,数字频率计,温度计,跑表等等,往往我们会选用

       led 数码管来做显示, 因为它驱动起来比 lcd 液晶要简单的很多,我们知道 fpga 中寄存器在定义和储存的数据都是采用二进制的格式 ,而 fpga 输出给数码

       管做显示的数据必须是十进制的格式 , 之前 bear 经常会选择把一个寄存器的个位和十位分开定义 ,比如在做数字时钟时 ,就会吧 时,分,秒的各位和十位

       都分别定义成一个变量  ,无疑这种方法会增加代码的复杂度 ,所以考虑需要一个专门把 二进制 的数据转换成 十进制 BCD码的模块 ,在网上有一些,但是好

       像都不太完整 , 所以bear花了一下午写了一个 ,亲测效果不错 ,希望对朋友们有所帮助,下面开始正文。

                

               首先给出二进制码转换为十进制BCD码的几个步骤(以8bit二进制码为例):

               1.将二进制码左移一位(或者乘2)

               2.找到左移后的码所对应的个,十,百位。

               3.判断在个位和百位的码是否大于5,如果是则该段码加3。

               4.继续重复以上三步直到移位8次后停止。

 

              下面是一个例子 ,将 1111_1111 转换为 BCD码 ,如果8bit数据最终移位得到18bit 数据 ,那么个位,十位,百位分别对应12~9,16~13,18~17位。                        

利用verilog将二进制码转换为十进制BCD码              

         之前写的代码在转换完之后没有对count清零,所以在仿真时候需要用rst_n清零,感谢博友onlytime417的提示,经过修改之后可以对不同的输入值连续转换,而不需要rst_n的复位,下面是修改后的代码以及仿真结果,(该转换模块已经在实际项目中应用)。

             

  CODE:          

`timescale 1ns / 1ps

module bin_dec(clk,bin,rst_n,one,ten,hun,count,shift_reg
    );
input  [7:0] bin;
input        clk,rst_n;
output [3:0] one,ten;
output [3:0] count;
output [1:0] hun;
output [17:0]shift_reg;
reg    [3:0] one,ten;
reg    [1:0] hun;
reg    [3:0] count;
reg    [17:0]shift_reg=18'b000000000000000000;
////////////////////// 计数部分 ////////////////////////
always @ ( posedge clk or negedge rst_n )
begin
 if( !rst_n )
   count<=0;
 else if (count==9)
   count<=0;
 else
   count<=count+1;
end

////////////////////// 二进制转换为十进制 /////////////////
always @ (posedge clk or negedge rst_n )
begin
  if (!rst_n)
       shift_reg=0;
  else if (count==0)
       shift_reg={10'b0000000000,bin};
  else if ( count<=8)                //实现8次移位操作
   begin
      if(shift_reg[11:8]>=5)         //判断个位是否>5,如果是则+3  
          begin
             if(shift_reg[15:12]>=5) //判断十位是否>5,如果是则+3  
                 begin
   shift_reg[15:12]=shift_reg[15:12]+2'b11;   
   shift_reg[11:8]=shift_reg[11:8]+2'b11;
shift_reg=shift_reg<<1;  //对个位和十位操作结束后,整体左移
 end
             else
       begin
                   shift_reg[15:12]=shift_reg[15:12];
shift_reg[11:8]=shift_reg[11:8]+2'b11;
shift_reg=shift_reg<<1;
 end
          end              
      else
          begin
             if(shift_reg[15:12]>=5)
                 begin
   shift_reg[15:12]=shift_reg[15:12]+2'b11;
   shift_reg[11:8]=shift_reg[11:8];
shift_reg=shift_reg<<1;
 end
             else
       begin
                   shift_reg[15:12]=shift_reg[15:12];
shift_reg[11:8]=shift_reg[11:8];
shift_reg=shift_reg<<1;
 end
          end        
  end
  end

/////////////////输出赋值//////////////////////////
always @ ( posedge clk or negedge rst_n )
begin
 if ( !rst_n )
  begin
    one<=0;
    ten<=0;
    hun<=0; 
  end
 else if (count==9)  //此时8次移位全部完成,将对应的值分别赋给个,十,百位
  begin
    one<=shift_reg[11:8];
ten<=shift_reg[15:12];
hun<=shift_reg[17:16]; 
  end
end
endmodule

   以下是仿真结果,bin为输入的二进制码,为了便于对比,仿真时也化成十进制显示了,one,ten,hun分别对应BCD码的个,十,百位。

修改前的仿真结果:

   利用verilog将二进制码转换为十进制BCD码  

   修改后的仿真结果:

利用verilog将二进制码转换为十进制BCD码