本文介绍verilog中使用移位法进行二进制转换十进制的方法。

在FPGA中,寄存器定义和存储的数据都是采用二进制的格式,而FPGA输 出给数码显示管的数据必须是十进制的格式,所以需要一个专门把二进制数据转 换为十进制BCD码的模块。图3为以十进制255举例的转换算法,具体算法流程为:

1) 二进制左移一位;

2) 判断个位、十位、百位是否大于等于5,是则加3;

3) 重复上述过程直到完成8次移位

移位法的优点是占用最少的片上资源实现进制转换的功能,相比传统不用脑子的本科生会写的除余进制转换电脑程序,在基础电路中的表现更加高效。

实例如下:

`timescale 1ns / 1ps


module bin_dec(clk,sec_start,bin,rst_n,one,ten,hun,count,shift_reg 
    ); 
input  [7:0] bin; 
input        clk,rst_n,sec_start; 
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 ) 
	begin 
	 if( !rst_n )  
		count<=0; 
	 else if(sec_start)
	   count<=0;
	 else if (count<=8) 
		count<=count+1; 
	 else 
		count<=9; 
	end


////////////////////// 二进制转换为十进制 ///////////////// 
always @ (posedge clk) 
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


该程序输出给另外的单个数码管输出模块即可,实现移位+3的转换方法。

并不明白具体原理,但是这个方法确实成功实现。待补充

以上。