我试着做一个16位到BCD转换。我已经找到了8位的链接,我正在尝试将其转换为16位。http://vhdlguru.blogspot.nl/2010/04/8-bit-binary-to-bcd-converter-double.html
我不知道我做错了什么,rpm_1000一直在变,rpm_100一直在4。有人知道我做错了什么吗?
process (Hex_Display_Data)
variable i : integer:=0;
variable bcd : std_logic_vector(19 downto 0) := (others => '0');
variable bint : std_logic_vector(15 downto 0) := Hex_Display_Data;
begin
for i in 0 to 15 loop -- repeating 16 times.
bcd(19 downto 1) := bcd(18 downto 0); --shifting the bits.
bcd(0) := bint(15); -- shift bit in
bint(15 downto 1) := bint(14 downto 0); --removing msb
bint(0) :='0'; -- adding a '0'
if(i < 15 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 < 15 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 < 15 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;
if(i < 15 and bcd(15 downto 12) > "0100") then --add 3 if BCD digit is greater than 4.
bcd(15 downto 12) := bcd(15 downto 12) + "0011";
end if;
end loop;
rpm_1000 <= bcd(15 downto 12);
rpm_100 <= bcd(11 downto 8);
rpm_10 <= bcd(7 downto 4);
rpm_1 <= bcd(3 downto 0);
end process ;发布于 2016-09-17 16:32:02
运行循环16次将导致BCD寄存器中的值乘以65536 (mod 100000)并添加到二进制寄存器中的值。假设值是4000。然后4000x65536产生44000。44000x65536产84000。84000x65536产24000。24000x65536的产量为64000。64000x65536的产量为4000。
要使算法工作,必须首先清除BCD寄存器。修复循环运行次数的注释也不会有什么害处。
顺便说一句,二进制到BCD转换器的实际实现通常应该接受时钟输入,并对每个活动时钟边缘执行一步。如果您的VHDL完全是在模拟中运行,那么所产生的逻辑的复杂性就无关紧要了,但是在实际硬件中同时执行所有操作将是相当昂贵的。相比之下,硬件实现二进制数的简单移位和BCD数的二乘二则要简单得多。请注意,如果“一次性”执行,输出中最重要的部分将取决于输入中第二个最不重要的部分,这意味着输入信号必须在一步内传播到所有逻辑中。相反,如果每时钟周期移动一位,则输出的每一位将只依赖于输入的最多四位(因为每一位数在调整阶段之前都在0-9范围内,添加3永远不会导致执行)。
此外,“双触碰”算法要求在BCD移位之前执行调整,但是看起来代码似乎是在之后执行调整。如果看位范围16.13、12.9、8.5和4..1而不是15..12等,则可以指定第19.17位的值应为第18..16位的值,第16.13位的值应为第15.12位(如果小于5)的值,或第15.12位的值,再加上3位(如果更大的话)等。这样的公式会将每一位的值设置在一个地方,这样就可以更容易地看到应该如何将其呈现到硬件中。
https://stackoverflow.com/questions/39548841
复制相似问题