原创 8.我与FPGA的恋爱之二进制码转换成BCD码

2016-4-15 19:51 965 15 15 分类: FPGA/CPLD 文集: 我与FPGA的恋爱

二进制码转换成BCD码

 我们使用逐步移位法来实现 BCD 的转换,在设计 FPGA 之前,我们先来了解一下 BCD 转换-逐步移位法的原理:

    逐步移位法的规则是:

    1. 准备一个 20 比特的移位寄存器;

    2. 二进数逐步左移;

    3. 每个 BCD 位做大四加三的调整 ;

    4. 二进数全部移完,得到结果;

为什么需要一个 20 比特的移位寄存器:由于输入信号是 8 位,如果用无符号来表示的话,输入信号的范围就是 0-255,而 BCD 码就是使用 4 位来表达一个数字, 255 有 3 个数字,所以 BCD 码的长度就是 4*3=12 比特,而需要准备的 20 比特移位寄存器就是 12 比特的 BCD 码+8 比特的输入信号。

20比特移位寄存器:

  第几次数  BCD_REG[19:16],BCD_REG[15:12],BCD_REG[11:8],BCD_REG[7:0]

2016-03-27_150952.jpg

通过表我们可以很明显的看出二进制通过移位转换成BCD码

 

下面我们通过表格中的转换方法,设计代码

 TOP.v
 module BCD(bin,bcd);
	input [7:0]bin;//二进制输入
	output [11:0]bcd;//BCD码输出
	
	wire [19:0] bcd_reg_0,
					bcd_reg_1,
					bcd_reg_2,
					bcd_reg_3,
					bcd_reg_4,
					bcd_reg_5,
					bcd_reg_6,
					bcd_reg_7,
					bcd_reg_8;//8次移位结果输出
	
	assign bcd_reg_0 = {12'b000_000_000_000,bin};//把输入的8位二进制转化为20位
	
	//例化调用
	bcd_modify b1(.data_in(bcd_reg_0),.data_out(bcd_reg_1));//第一次移位
	bcd_modify b2(.data_in(bcd_reg_1),.data_out(bcd_reg_2));//第一次移位
	bcd_modify b3(.data_in(bcd_reg_2),.data_out(bcd_reg_3));//第一次移位
	bcd_modify b4(.data_in(bcd_reg_3),.data_out(bcd_reg_4));//第一次移位
	bcd_modify b5(.data_in(bcd_reg_4),.data_out(bcd_reg_5));//第一次移位
	bcd_modify b6(.data_in(bcd_reg_5),.data_out(bcd_reg_6));//第一次移位
	bcd_modify b7(.data_in(bcd_reg_6),.data_out(bcd_reg_7));//第一次移位
	bcd_modify b8(.data_in(bcd_reg_7),.data_out(bcd_reg_8));//第一次移位
	
	assign bcd = {bcd_reg_8[19:8]};//取高12位输出

endmodule

module bcd_modify(data_in,data_out);

	input [19:0]data_in;//需要移位比较数据输入
	output [19:0]data_out;//移位比较完成数据输出
	
	wire [3:0] bcd_reg_1,bcd_reg_2,bcd_reg_3;//三次移位结果输出
	//<=> bcd0[3:0],bcd1[4:7],bcd[8:11]
	
	cmp c1(.cmp_in(data_in[19:16]),.cmp_out(bcd_reg_1));//data_in[19:16]进行大四加三比较
	cmp c2(.cmp_in(data_in[15:12]),.cmp_out(bcd_reg_2));//data_in[15:12]进行大四加三比较
	cmp c3(.cmp_in(data_in[11:8]),.cmp_out(bcd_reg_3));//data_in[11:8]进行大四加三比较
	
	assign data_out = {bcd_reg_1[2:0],bcd_reg_2,bcd_reg_3,data_in[7:0],1'b0};
	//data_in[19:8]全部比较完成后,左移一位
	
endmodule


module cmp(cmp_in,cmp_out);
	input [3:0]cmp_in;//比较器数据输入
	output [3:0]cmp_out;//输出
	
	
	/*----------------说明------------------------
	//	以表中数据为例 第三次数据为 :	101
	//	进行正常移位 第四次数据应该为: 1010 
	//	进行大四加三后 第四次数据变为 : 1000 = 101 +3
	//	大四加三算法:输入得原数据进行与,或运算
	//	第一步: A = cmp[1] | cmp[0] = 1
	//	第二步: B = cmp[2] & A = 0
	//	第三步: C = cmp[3] | B = 1
	//	第四步: C >= 1 : cmp_out = cmp + 3
	---------------------------------------------*/
	
	assign cmp_out = ( ( cmp_in[3] | ( cmp_in[2] & ( cmp_in[1] | cmp_in[0] )))) ? (cmp_in + 3):cmp_in;
	//输出数据 = 输入数据大四加三
	
endmodule	


///////////`tb

`timescale 1ns/1ns
`define clock_period 20

module BCD_tb;

	reg clk;
	reg [7:0]bin;
	
	wire [11:0]bcd;
	
	BCD BCD(.bin(bin),.bcd(bcd));
	
	initial clk = 0;
	always #(`clock_period/2) clk = ~clk;
	
	initial begin
			bin = 8'b0;
	end
	
	always @(posedge clk)
		begin
			bin <= bin + 1'b1;
		end
	

endmodule

 

比次笔记后续还有两部分未完成,分别为

1,BCD码转换二进制

2.BCD码计数器

由于本人能力有限,出错之处的请各位给予帮助.谢谢!

 

 更多资料参考

                发烧友小梅哥专版 http://bbs.elecfans.com/zhuti_fpga_1.html

                   梦翼师兄的炼狱传奇

文章评论0条评论)

登录后参与讨论
我要评论
0
15
关闭 站长推荐上一条 /2 下一条