一直感覺這是個(gè)很簡(jiǎn)單的問(wèn)題,直到突然自己連BCD都不太清楚的時(shí)候,才發(fā)現(xiàn)這沒有看起來(lái)那么簡(jiǎn)單,這里介紹里任意位二進(jìn)制轉(zhuǎn)為BCD的verilog代碼,這個(gè)轉(zhuǎn)換方法也可以用在C上面,此為原創(chuàng),轉(zhuǎn)載請(qǐng)注明,謝謝。
基礎(chǔ)知識(shí):
BCD:BCD碼又稱為8421碼,
意義:之所以有時(shí)候需要將binary轉(zhuǎn)換為BCD,一般是用在本科的實(shí)驗(yàn)中,為了將binary顯示在數(shù)碼管中,當(dāng)然還有很多應(yīng)用,只是目前我還沒有用到。
轉(zhuǎn)換算法:左移加3法
移位加3法的具體原理,在網(wǎng)上感覺也沒有人能夠說(shuō)的清楚,以后找到書籍再說(shuō)吧。下面解釋下左移加三算法。這里以8bit二進(jìn)制數(shù)FF做例子。

該算法的操作為上圖。下面對(duì)上圖的操作進(jìn)行詳細(xì)的解釋:
由于8bit的二進(jìn)制最大為FF,轉(zhuǎn)換為十進(jìn)制為255。所以需要使用三個(gè)BCD碼來(lái)表示所有的8bit二進(jìn)制數(shù)。上圖的hundreds表示百位的BCD,tens表示十位的BCD,Units表示個(gè)位的BCD。算法的操作為一直將binary數(shù)據(jù)左移,移出的數(shù)據(jù)按順序存在hundreds,tens,Units。例如上面的shift1,shift2,shift3操作后,Units變?yōu)榱?111,至于為何在shift3后進(jìn)行add3操作,是因?yàn)樵谒惴ㄖ忻恳淮巫笠,都要?duì)hundreds,tens和Units進(jìn)行判斷,如果hundreds,tens和Units里面的值大于或等于5,就將hundreds,tens和Units自加3.所以shift3后,Units里面為0111,表示為7,此時(shí)不能左移,而是對(duì)Units加三操作,所以Units的值從0111變?yōu)榱?010.值得注意的是,只要hundreds,tens和Units中任意一個(gè)的值大于或等于5(0101),就要先進(jìn)行一次自加三的操作,然后才能繼續(xù)左移,后面的操作同上。
注意2:n位的binary就需要進(jìn)行n次左移
注意3:最后一次左移不需要進(jìn)行add3操作
注意4
: 親自推導(dǎo)16位的,和24位的binary轉(zhuǎn)換,結(jié)果正確,所以該算法適用于任意位binary
to BCD,當(dāng)然這種論斷沒有足夠的理論依據(jù)。
verilog代碼:
說(shuō)明:對(duì)于8bit及以下的binary,可以使用case語(yǔ)句實(shí)現(xiàn)移位加三算法。由于這里說(shuō)明的是任意位的二進(jìn)制數(shù),轉(zhuǎn)為BCD,所以我的代碼中設(shè)計(jì)了一個(gè)狀態(tài)機(jī),來(lái)控制移位,加三和結(jié)束操作。由于代碼編寫時(shí)間倉(cāng)促,其中或許有些bug。
//name:
二進(jìn)制轉(zhuǎn)BCD
//data: 2014-04-17 at kb129
//info: as 2**8=255 change to BCD then this need
3 times of “8421”
module b_to_bcd(
clk,
rst_n,
binary,
state_en,
BCD
);
parameter
b_length
= 8;
parameter
bcd_len
= 12;
parameter
idle
= 5'b00001;
parameter
shift
= 5'b00010;
parameter
wait_judge = 5'b00100;
parameter
judge
= 5'b01000;
parameter
add_3
= 5'b10000;
input
clk;
input
rst_n;
input
[b_length-1:0]
binary;
input state_en;
output reg [bcd_len-1:0]
BCD;
reg
[b_length-1:0]
reg_binary;
reg [3:0]
bcd_b, bcd_t,
bcd_h;
reg [3:0]
shift_time;
reg [5:0]
c_state,
n_state;
reg add3_en;
reg change_done;
//this is a three section kind of state code
style
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
c_state <= idle;
else
c_state <= n_state;
end
//the second section
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
c_state <= idle;
else
case(n_state)
idle:begin
if((binary!=0)&&(state_en==1'b1)&&(change_done==0'b0))
n_state <= shift;
else
n_state <= idle;
end
shift: n_state <= wait_judge;
wait_judge:
begin