VDHL固定解码代码无法正常工作
我正在使用David bishop的定点库在vhdl中做了一些数学计算。我需要将最终值解码为整数。我遵循的方法如下,我确实得到了小数部分的精确值,但小数值不正确。我还没找到问题。在小数部分前两位数字是错误的。 xx 8374.839923 xx数字总是错的。VDHL固定解码代码无法正常工作
当我执行,我得到 74334.738295为 74334.738295
内部架构, 内部过程中,我做的声明这些变量,
variable cp : sfixed(20 downto -19);
variable mod10 : sfixed(4 downto 0);
variable div10 : sfixed(4 downto 0);
variable L0 : sfixed(4 downto 0);
variable L1 : sfixed(4 downto -4);
variable L2 : sfixed(4 downto -8);
variable L3 : sfixed(4 downto -12);
variable L4 : sfixed(4 downto -16);
variable L5 : sfixed(4 downto -20);
variable L6 : sfixed(4 downto -24);
variable temp_L : sfixed(19 downto 0);
variable temp_L1 : sfixed(20 downto -4);
variable temp_L2 : sfixed(21 downto -8);
variable temp_L3 : sfixed(22 downto -12);
variable temp_L4 : sfixed(23 downto -16);
variable temp_L5 : sfixed(24 downto -20);
variable temp_L6 : sfixed(25 downto -24);
开始后,我需要解码174334.738295在sfixed,因为有时我得到负数。这个数字被另一个计算,在此未提供,如果该号码是174334.738295(sfixed)代替然后我需要解码此号码,
cp := to_sfixed(174334.738295,20,-19);
temp_L := cp(19 downto 0); -- remove sign bit
mod10 :=to_sfixed(10,4,0) ;
div10 :=to_sfixed(10,4,0) ;
L0 := temp_L mod mod10;
temp_L1 := temp_L/div10;
L1 := temp_L1 mod mod10;
temp_L2 := temp_L1/div10;
L2 := temp_L2 mod mod10;
temp_L3 := temp_L2/div10;
L3 := temp_L3 mod mod10;
temp_L4 := temp_L3/div10;
L4 := temp_L4 mod mod10;
temp_L5 := temp_L4/div10;
L5 := temp_L5 mod mod10;
temp_L6 := temp_L5/div10;
L6 := temp_L6 mod mod10;
L6是第1位和L5是第二位。
修改您与修复DIV10,MOD10原代码(用下划线独自一人出走声明)和生产MCVE:
library ieee;
use ieee.fixed_pkg.all;
entity iopertyki is
end entity;
architecture fum of iopertyki is
begin
process
variable cp: sfixed(20 downto -19);
variable mod_10: sfixed(4 downto 0);
variable div_10: sfixed(4 downto 0);
variable mul_10: sfixed(4 downto 0);
variable L0: sfixed(4 downto 0);
variable L1: sfixed(4 downto -4);
variable L2: sfixed(4 downto -8);
variable L3: sfixed(4 downto -12);
variable L4: sfixed(4 downto -16);
variable L5: sfixed(4 downto -20);
variable L6: sfixed(4 downto -24);
variable temp_L: sfixed(19 downto 0);
variable temp_L1: sfixed(20 downto -4);
variable temp_L2: sfixed(21 downto -8);
variable temp_L3: sfixed(22 downto -12);
variable temp_L4: sfixed(23 downto -16);
variable temp_L5: sfixed(24 downto -20);
variable temp_L6: sfixed(25 downto -24);
begin
cp := to_sfixed(174334.738295,20,-19);
report "cp = " & to_string(cp);
temp_L := cp(19 downto 0); -- remove sign bit
report "temp_L = " & to_string(temp_L);
report "integer'image temp_L = " & integer'image(to_integer(temp_L));
mod_10 := to_sfixed(10,4,0);
div_10 := to_sfixed(10,4,0);
mul_10 := to_sfixed(10,4,0);
L0 := temp_L mod mod_10;
temp_L1 := temp_L/div_10;
L1 := temp_L1 mod mod_10;
temp_L2 := temp_L1/div_10;
L2 := temp_L2 mod mod_10;
temp_L3 := temp_L2/div_10;
L3 := temp_L3 mod mod_10;
temp_L4 := temp_L3/div_10;
L4 := temp_L4 mod mod_10;
temp_L5 := temp_L4/div_10;
L5 := temp_L5 mod mod_10;
temp_L6 := temp_L5/div_10;
L6 := temp_L6 mod mod_10;
-- xx8374.839923 ?
report " result = " & integer'image(to_integer(L6)) &
integer'image(to_integer(L5)) &
integer'image(to_integer(L4)) &
integer'image(to_integer(L3)) &
integer'image(to_integer(L2)) &
integer'image(to_integer(L1)) &
integer'image(to_integer(L0));
report " no round = " & integer'image(to_integer(L6(4 downto 0))) &
integer'image(to_integer(L5(4 downto 0))) &
integer'image(to_integer(L4(4 downto 0))) &
integer'image(to_integer(L3(4 downto 0))) &
integer'image(to_integer(L2(4 downto 0))) &
integer'image(to_integer(L1(4 downto 0))) &
integer'image(to_integer(L0(4 downto 0)));
wait;
end process;
end architecture;
由此产生的整数部分结果(你不演示如何在这样做您的问题,用新的结果:
...得到274334.738295为174334.738295
可以证明to_integer四舍五入负责L5为2,而不是1:
ghdl -a --std=08 iopertyki.vhdl ghdl -e --std=08 iopertyki ghdl -r iopertyki iopertyki.vhdl:91:9:@0ms:(report note): cp = 000101010100011111110.1011110100000000111 iopertyki.vhdl:93:9:@0ms:(report note): temp_L = 00101010100011111110.0 iopertyki.vhdl:94:9:@0ms:(report note): integer'image temp_L = 174334 iopertyki.vhdl:113:9:@0ms:(report note): result = 0274334 iopertyki.vhdl:121:9:@0ms:(report note): no round = 0174334
所以这一切都告诉你只使用L6的整数部分 - 所以没有四舍五入L1。 (有关如何剪裁固定值或不固定值的提示可以在您评论的David Bishop用户指南中使用)。
你可能会注意到,裁剪一个sfixed值会受到符号偏差的影响,并且您需要更改所有恢复的十进制数字的符号或使用带符号的幅度(其中您的数字计算可能被固定)标志转发给负数的结果。几十年来的数学可能非常麻烦。使用ghdl当在阐述和仿真
注
有代码生成的三种架构为ghdl,使用GCC后端,一个LLVM后端和刚刚在时间码发生器的的MCode。
从上Invoking GHDL最新GHDL Documentation部为运行命令:
奔跑/模拟设计。选项和参数与制作命令中的 相同。
- GGC/LLVM:简单地说,确定可执行文件的文件名并执行它。选项被忽略。您也可以直接执行 该程序。可执行文件必须位于当前目录中。
- mcode:设计被阐述并且仿真被启动。因此,您必须使用分析过程中使用的相同选项。
在一个版本的MCode诸如分布式为Win32的-e精心命令是多余的,且运行命令(-r)必须包括相同的选项作为分析命令(-a)。
对于GCC/LLVM后端codegenerator版本的ghdl,elaborate(-e)命令必须与分析命令(-a)具有相同的选项。对于--std=08
,将使用不同的工作库,如果没有单独指定库目录,则会覆盖不带std选项或具有不同STD值的任何目标文件。
mcode版本没有目标文件。分析的对象只存在于ghdl程序的内存中,随后通过run(-r)命令将其分析为仿真设计模型。
没有指定版本或发布ghdl用户只能依赖ghdl文档。
您还可以注意到ghdl-0.34已在最后一天发布,并且有一个Win32二进制图像(mcode)和64位二进制图像(llvm)可用(它们的名称包括“mingw”)。
你能告诉我你使用的模拟器是什么? – iopertyki
[ghdl](https://ghdl.readthedocs.io/en/latest/Introduction.html) – user1155120
如何将定点包包含到ghdl?我得到错误,主库“fixed_pkg”未在库中找到“工作” – iopertyki
你的部门应该是整数部门;他们不是(定点部门)。而且我甚至都不会想象当应用于非整数(定点)参数时模运算符应该返回什么。无论如何,这个固定点表示相当简单,所以,如果你只是想要一个积极的定点数的整数部分的数字,你可以先将其转换为自然的,然后计算位数:
library ieee;
use ieee.numeric_std.all;
use ieee.std_logic_1164.all;
...
variable n: natural;
subtype digit is natural range 0 to 9;
type digit_vector is array(natural range <>) of digits;
variable digits: digit_vector(5 downto 0);
...
n := to_integer(u_unsigned(cp(20 downto 0)));
for i in 0 to 5 loop
digits(i) := n mod 10;
n := n/10;
end loop;
或者,如果你只是想打印的cp
十进制表示:
use std.textio.all;
...
variable l: line;
...
write(l, to_integer(u_unsigned(cp(20 downto 0)));
writeline(output, n);
,或者更简单,使用write
程序从库本身:
variable tmp: sfixed(20 downto 0);
...
tmp := cp(20 downto 0);
write(l, tmp);
writeline(output, l);
我不知道负指标是可能的。不过,我不会使用它们。 –
@Oron Port请参考David Bishop的定点lib手册! – iopertyki
固定和浮点库是开源的,并存储在GitHub:https://github.com/fphdl/fphdl。你可以在那里打开一个问题,并要求更详细的帮助。您还应该将您当前的副本与最新版本进行比较。这就是将在VHDL-2017中发布的版本。 – Paebbels