二进制码转换成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]
通过表我们可以很明显的看出二进制通过移位转换成BCD码
下面我们通过表格中的转换方法,设计代码
TOP.v
moduleBCD(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次移位结果输出
assignbcd_reg_0={12'b000_000_000_000,bin};//把输入的8位二进制转化为20位
//例化调用
bcd_modifyb1(.data_in(bcd_reg_0),.data_out(bcd_reg_1));//第一次移位
bcd_modifyb2(.data_in(bcd_reg_1),.data_out(bcd_reg_2));//第一次移位
bcd_modifyb3(.data_in(bcd_reg_2),.data_out(bcd_reg_3));//第一次移位
bcd_modifyb4(.data_in(bcd_reg_3),.data_out(bcd_reg_4));//第一次移位
bcd_modifyb5(.data_in(bcd_reg_4),.data_out(bcd_reg_5));//第一次移位
bcd_modifyb6(.data_in(bcd_reg_5),.data_out(bcd_reg_6));//第一次移位
bcd_modifyb7(.data_in(bcd_reg_6),.data_out(bcd_reg_7));//第一次移位
bcd_modifyb8(.data_in(bcd_reg_7),.data_out(bcd_reg_8));//第一次移位
assignbcd={bcd_reg_8[19:8]};//取高12位输出
endmodule
modulebcd_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]
cmpc1(.cmp_in(data_in[19:16]),.cmp_out(bcd_reg_1));//data_in[19:16]进行大四加三比较
cmpc2(.cmp_in(data_in[15:12]),.cmp_out(bcd_reg_2));//data_in[15:12]进行大四加三比较
cmpc3(.cmp_in(data_in[11:8]),.cmp_out(bcd_reg_3));//data_in[11:8]进行大四加三比较
assigndata_out={bcd_reg_1[2:0],bcd_reg_2,bcd_reg_3,data_in[7:0],1'b0};
//data_in[19:8]全部比较完成后,左移一位
endmodule
modulecmp(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
---------------------------------------------*/
assigncmp_out=((cmp_in[3]|(cmp_in[2]&(cmp_in[1]|cmp_in[0]))))?(cmp_in+3):cmp_in;
//输出数据=输入数据大四加三
endmodule
///////////`tb
`timescale1ns/1ns
`defineclock_period20
moduleBCD_tb;
regclk;
reg[7:0]bin;
wire[11:0]bcd;
BCDBCD(.bin(bin),.bcd(bcd));
initialclk=0;
always#(`clock_period/2)clk=~clk;
initialbegin
bin=8'b0;
end
always@(posedgeclk)
begin
bin<=bin+1'b1;
end
endmodule