我们可以看到,在VHDL中,MOD和REM只能模拟,不能合成。那么我们如何从无符号整数中得到BCD呢?比如整数是23,怎么得到BCD:0b0010和0b0011呢?谢谢。
3 回答
我在下面提供了两个 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(所以用户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;
注意:您可以使用以下链接中的信息将整数转换为无符号数,将整数转换为 std_logic
这已在其他地方介绍过:
https://electronics.stackexchange.com/questions/22611/binary-to-bcd-converison
- 查找表是一种选择
- 一个大的 case 语句是另一个(它将变成一个查找表)
- 或者一种迭代方法,您不断减去 10 直到余数 < 10 - 减法计数是您的十位数,余数是您的个位数。
您可能有兴趣查看“双重涉猎”算法:
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 寄存器(使用+3
任何数字大于 4 时的规则),BCD 表示0010 0011
(23)。
有关更多详细信息,请参阅维基百科文章。您甚至可以找到 VHDL 实现的示例。