如何使用VHDL将无符号整数解码为BCD

3

如我们所知,在VHDL中,MOD和REM只能被模拟而不能被合成。那么我们该如何从一个无符号整数中获取BCD码呢?例如,整数为23,我们该如何获得BCD码:0b0010和0b0011?

谢谢。

3个回答

1

我提供了以下两个VHDL函数。这是用于将二进制转换为紧缩BCD和反之亦然。我已在Xilinx Spartan 3AN系列上验证过它们,并且可以合成。请使用ieee.numeric_std.all;ieee.std_logic_1164.all;库。

函数1:二进制到BCD --来源:http://vhdlguru.blogspot.com.es/2010/04/8-bit-binary-to-bcd-converter-double.html(SO用户Peque找到了原始网址)

    function to_bcd ( bin : unsigned(7 downto 0) ) return unsigned is
        variable i : integer:=0;
        variable bcd : unsigned(11 downto 0) := (others => '0');
        variable bint : unsigned(7 downto 0) := bin;

        begin
        for i in 0 to 7 loop  -- repeating 8 times.
        bcd(11 downto 1) := bcd(10 downto 0);  --shifting the bits.
        bcd(0) := bint(7);
        bint(7 downto 1) := bint(6 downto 0);
        bint(0) :='0';


        if(i < 7 and bcd(3 downto 0) > "0100") then --add 3 if BCD digit is greater than 4.
        bcd(3 downto 0) := bcd(3 downto 0) + "0011";
        end if;

        if(i < 7 and bcd(7 downto 4) > "0100") then --add 3 if BCD digit is greater than 4.
        bcd(7 downto 4) := bcd(7 downto 4) + "0011";
        end if;

        if(i < 7 and bcd(11 downto 8) > "0100") then  --add 3 if BCD digit is greater than 4.
        bcd(11 downto 8) := bcd(11 downto 8) + "0011";
        end if;

    end loop;
    return bcd;
    end to_bcd;

功能 2:BCD 到二进制

    --(c)2012 Enthusiasticgeek for Stack Overflow. 
    --Use at your own risk (includes commercial usage). 
    --These functions are released in the public domain and 
    --free to use as long as this copyright notice is retained.

    --multiplication by 10 is achieved using shift operator   X<<3 + X<<1
    --input should be packed BCD.
    function to_binary ( bcd : unsigned(11 downto 0) ) return unsigned is
        variable i : integer:=0;
        variable binary : unsigned(7 downto 0) := (others => '0');  
        variable temp : unsigned(6 downto 0) := (others => '0');
        variable bcdt : unsigned(11 downto 0) := bcd;   
        variable tens : unsigned(7 downto 0) := (others => '0');
        variable hundreds_stepI : unsigned(7 downto 0) := (others => '0');
        variable hundreds_stepII : unsigned(7 downto 0) := (others => '0');

       begin

         for i in 0 to 11 loop  -- repeating 12 times.

         if(i >=0 and i<4) then
            binary := ((temp&bcdt(i) ) sll i ) + binary;
         end if;         

         if(i >=4 and i<8) then         
            tens := (((temp&bcdt(i) ) sll (i-4) ) sll 3) + (((temp&bcdt(i) ) sll (i-4) ) sll 1); --multiply by 10           
            binary := tens + binary;
         end if;         

         if(i >=8 and i<12) then         
            hundreds_stepI := (((temp&bcdt(i) ) sll (i-8) ) sll 3) + (((temp&bcdt(i) ) sll (i-8) ) sll 1); --multiply by 10
            hundreds_stepII := (hundreds_stepI sll 3) + (hundreds_StepI sll 1); -- multiply by 10 again so the effect is now multiply by 100                
            binary := hundreds_stepII + binary;
         end if;

         end loop;     

       return binary;
    end to_binary;

注意:您可以使用以下链接中的信息将整数转换为无符号 convert integer to std_logic

1
-1 表示在不是你自己的代码中添加版权声明:http://vhdlguru.blogspot.com.es/2010/04/8-bit-binary-to-bcd-converter-double.html - Peque
@Peque,你说得对。我想我复制并粘贴了我所有VHDL代码的版权模板。我写了to_binary(据我所知-那是三年前)。我通常在适用的情况下提供参考文献-不知何故我可能错过了这个。已更新答案。感谢您指出。 - enthusiasticgeek

1

0

你可能会对“双倍运算”算法感兴趣:

http://en.wikipedia.org/wiki/Double_dabble

基本上,您要做的是为BCD表示法创建一个寄存器,该寄存器位于整数表示法的“左侧”。以下是一个示例,其中我们希望将数字23转换为其BCD表示法:

BCD_1  BCD_0      Original
0000   0000       10111

现在你需要创建一个for循环,其中将原始位向左移动(将这些位推入BCD寄存器中)。在此循环中,必须检查每个BCD_X数字是否大于4;如果是,则将3添加到该数字:

shift_iteration   BCD_1  BCD_0      Original
0                 0000   0000       10111
1                 0000   0001       01110       (no digit greater than 4)
2                 0000   0010       11100       (no digit greater than 4)
3                 0000   0101       11000       (5 in BCD_0! we add 3...)
still 3...        0000   1000       11000       (after addition, shift again)
4                 0001   0001       10000       (no digit greater than 4)
5                 0010   0011       00000       (no digit greater than 4)

一旦您将所有原始位数推送到BCD寄存器中(在任何数字大于4时使用+3规则),BCD代表的是0010 0011(23)。

更多详情请参见维基百科文章。您甚至可以找到VHDL实现的示例。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接