【问题标题】:How to decode an unsigned integer into BCD use VHDL如何使用 VHDL 将无符号整数解码为 BCD
【发布时间】:2012-10-18 09:47:27
【问题描述】:

如我们所见,在VHDL中,MOD和REM只能模拟,不能合成。那么我们如何从无符号整数中得到BCD呢?比如整数是23,怎么得到BCD:0b0010和0b0011呢? 谢谢。

【问题讨论】:

    标签: integer vhdl bcd


    【解决方案1】:

    这已在其他地方介绍过:

    https://electronics.stackexchange.com/questions/22611/binary-to-bcd-converison

    • 查找表是一种选择
    • 一个大的 case 语句是另一个(它将变成一个查找表)
    • 或一种迭代方法,您不断减去 10,直到余数小于 10 - 减法的计数是您的十位数,余数是您的个位数。

    【讨论】:

      【解决方案2】:

      我在下面提供了两个 VHDL 函数。这是从二进制转换为压缩 BCD,反之亦然。我已经在 Xilinx Spartan 3AN 系列上验证了这些,它们可以合成。使用 ieee.numeric_std.all;ieee.std_logic_1164.all;

      功能1:二进制转BCD --source:http://vhdlguru.blogspot.com.es/2010/04/8-bit-binary-to-bcd-converter-double.html(所以用户Peque找到了原来的url)

          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 用于向不属于您自己的代码添加版权声明:vhdlguru.blogspot.com.es/2010/04/…
      • @Peque 是的,你是对的。我想我为这两个代码复制并粘贴了所有 VHDL 的版权模板。我写信给 to_binary(据我所知——那是三年前的事)。我通常会在适用的情况下提供参考 - 不知何故,我一定错过了这个。更新了答案。感谢您指出。
      【解决方案3】:

      您可能有兴趣了解一下“双重涉猎”算法:

      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 实现的示例。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-11-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多