//二进制数到BCD译码器模块
module BIN2BCD(CLK, ENABLE, RESET, BIN, BCD_T, BCD_H, BCD_D, BCD_U);
input CLK;
input ENABLE;
input RESET;
input [9:0] BIN;
output [3:0] BCD_T;
output [3:0] BCD_H;
output [3:0] BCD_D;
output [3:0] BCD_U;
integer CNT;
reg [15:0] BCD;
reg [9:0] BIN_INPUT;
reg [3:0] BCD_T_I; BCD_H_I, BCD_D_I, BCD_U_I;
function [3:0] CORRECT;
// The CORRECT function adds 3 when the number is equal or more than 5
input [3:0] DECADE;
begin
CORRECT = (DECADE >= 5)?(DECADE+3):(DECADE);
end
endfunction
always @ (posedge CLK or posedge RESET)
begin
if(RESET) //asynhronous reset
begin
//conversion takes 10 clock cycles
CNT = 11;
BCD = 16'b0000_0000_0000_0000;
//below line is necessary for Metamor VHDL complier
//Metamor Reports: WARNING : Flip-flop 'BIN_INPUT' has missing set or reset
BIN_INPUT = 11'b0000_0000_000;
BCD_T_I = 4'b0000;
BCD_H_I = 4'b0000;
BCD_D_I = 4'b0000;
BCD_U_I = 4'b0000;
end
else //active clock edge
begin
if(ENABLE)
begin
if(CNT ==11)
begin
//start conversion; latch input BIN number
BIN_INPUT = BIN;
CNT = CNT -1;
end
else if (CNT == 0)
begin
//end of conversion; latch BCD outputs
BCD_T_I = BCD[15:12];
BCD_H_I = BCD[11:8];
BCD_D_I = BCD[7:4];
BCD_U_I = BCD[3:0];
end
else
begin
//correction of each BCD tetrade: adding 3 before shifting
//below 4 lines are synthesized as 4 identical combinatorial blocks
//each block implements CORRECT functionality
BCD[3:0] = CORRECT(BCD[3:0]);
BCD[7:4] = CORRECT(BCD[7:4]);
BCD[11:8] = CORRECT(BCD[11:8]);
BCD[15:12] = CORRECT(BCD[15:12]);
//conversion section
CNT = CNT -1;
//shift one bit left the BCD register
BCD = (BCD<<1);
//MSB bit of BIN is shifted as LSB of BCD
BCD[0] = BIN_INPUT[9];
//shift one bit left the BIN_INPUT number
BIN_INPUT = BIN_INPUT<<1;
end
end
end
end
assign BCD_T = BCD_T_I;
assign BCD_H = BCD_H_I;
assign BCD_D = BCD_D_I;
assign BCD_U = BCD_U_I;
endmodule
2008年08月20日 | 12:59分类:技术体 | 标签:bcdbin译码器 | 1,834 views
昨儿碰到一个不大不小的问题。就是一个十位的二进制数,如何转化成一个16位的BCD码(这里用8421码),也就是一个普通的十进制的四位数的问题。不是换算,是用具体的电路实现。
其实我有一段Verilog的源代码(是时序触发的,不过,我还没想到用组合逻辑要怎么搞……)。只不过看不懂,后来google之,果然得到老外的一段英文,看了以后就悟了。鉴于这问题有点意思,就发上来给大家看看。
喜欢Verilog的看这个,习惯vhdl的可以看这个。对一切HDL语言都没兴趣的人(即如果你既不知道Verilog,又不知道VHDL),可以略过这两段,直接看下面。
操作是这样的:用两个寄存器,一个10bit,一个16bit,分别存bin码和有待实现的bcd码。接下来,逐位将BIN的最高位移入BCD的最低位。同时,将BCD的16位寄存器按每四位划成一块,我们称之为个十百千好了。但记住,个,十,百,千都有4个bit位。
1.将bin[9](bin是bin[9:0])移入bcd[0]。这样,bin[9]就变成了原来的bin[8],bin[0]=0。
2.分别检查个十百千里存的数是不是大于等于5(按二进制换十进制那样换算),如果是,加3。
3.重做1,2。直到全部移进去。
原理是这样的:
bin和bcd的表示方法的差别,就在于10用bin表示为1010,用bcd表示成10000。但左移一位就是乘2,这个是没问题的。因此,如果不做2的操作,就等于不停的把个位数乘2加上新的个位数,这样还是原来的数。做了2之后,就等于把原来的1010变成10000,因为1010在bcd码里是不可能出现的,因此要把10变成bin下面的16。而5=10/2,3=(16-10)/2,也等于(18-12)/2……等等等等