VDHL sfixed解码码不能正常工作[英] VDHL sfixed decoding code does not work properly

本文是小编为大家收集整理的关于VDHL sfixed解码码不能正常工作的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

我正在使用 David Bishop的固定点库在VHDL中进行一些数学.我需要将最终值解码为整数.我所遵循的方法如下,我确实获得了分数零件的良好价值,但是小数值不正确.我还找不到这个问题.在十进制部分中,第一个数字是错误的. xx 8374.839923 xx 数字总是错误的.

当我执行此操作时,我会得到 2 74334.738295 1 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);

开始后,我需要在Sfixed中对174334.738295进行解码,因为有时候我会得到负数.这个数字将被另一个计算替换,如果该数字为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是第一位数,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 17433.738295

您可以证明to_integer Founding是L5的原因,而不是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的用户指南将如何剪辑SFIX或UFIX的值如何).

您可能会注意到,将Sfix的值剪切会受到符号偏差的约束,并且您要么需要更改所有恢复的小数位数的标志,要么使用符号幅度(可能会在数字计算的情况下使用符号),并带有标志转发到负数的结果.几十年来数学可能很麻烦.

使用GHDL

时的阐述和模拟说明

使用GCC后端,LLVM后端和时间代码生成器中的MCODE,有三个用于GHDL的代码生成的体系结构.

来自最新的 ghdl document href =" http://ghdl.readl.readthedocs.io/en/new-documentation-schrenture/using/invokingghdl.html" rel =" nofollow noreferrer"> invoking ghdl 用于运行命令:

run -r

运行/模拟设计.选项和论点与 阐述命令.

  • GGC/LLVM:简而言之,确定可执行文件的文件名并执行.选项被忽略.您也可以直接执行 该程序.可执行文件必须在当前目录中.
  • MCODE:设计已详细介绍,并启动了模拟.结果,您必须使用分析过程中使用的相同选项.

在MCODE版本中,例如Win32的分布式版本,-e详细命令是冗余的,Run命令(-r)必须包含与分析命令(-a)相同的选项.

对于GHDL的GCC/LLVM后端代码generator版本,详细的(-e)命令必须具有与Analysis命令(-a)相同的选项.对于--std=08,使用了不同的工作库,如果未单独指定库目录,则没有STD选项或具有不同的STD值的任何对象文件被覆盖.

MCODE版本没有对象文件.分析的对象仅存在于GHDL程序的内存中,随后将运行(-r)命令详细阐述为仿真设计模型.

无需指定版本或发布用户只能依靠GHDL文档.

您还可以注意, ghdl-0.34 已发布在最后一天,可以使用Win32二进制图像(MCODE)和64位二进制图像(LLVM)(它们的名称包括" mingw").

其他推荐答案

您的部门应该是整数划分;它们不是(固定点划分).而且,我什至没有想象将模量运算符应用于非整数(固定点)参数时应该返回什么.无论如何,此固定点表示非常简单,因此,如果您只想要正固定点号的整数部分的数字,则可以首先将其转换为自然,然后计算数字:

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);

本文地址:https://www.itbaoku.cn/post/2090957.html

问题描述

I am using David bishop's fixed point library to do some math in vhdl. and i need to decode the final value into integers. the method i have followed as below, and i do get fine value for fractional part but the decimal value is not correct. i could not find the issue yet. in decimal part 1st two digits are wrong. xx8374.839923 xx numbers are wrong always.

when i perform this, i get 274334.738295 for 174334.738295

inside architecture, inside process i do declare these variables,

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);

after begin, i need to decode 174334.738295 in sfixed, because some times i get negative number. this number is to replaced by another calculation, which is not provided here, if that number is 174334.738295 (sfixed) then i need to decode this number,

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 is the 1st digit and L5 is the 2nd digit.

推荐答案

Modifying your original code with fixes for div10, mod10 (with underscores leaving the declarations alone) and producing an 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;

This produces the integer part result (you don't demonstrate how you did this in your question, with the new results:

...get 274334.738295 for 174334.738295

You can demonstrate that to_integer rounding is responsible for L5 being 2 instead of 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

So all this tells you to only use the integer part of L6 - L1 so there is no rounding. (There's a hint for how clipping an sfixed or ufixed value will work in David Bishop's user guide you commented on).

You could note that clipping an sfixed value will be subject to a sign bias and that you'd either need to change sign of all the recovered decimal digits or use signed magnitude (where your digit calculations might be ufixed) with the sign forwarded to the result for negative numbers. Math in decades can be cumbersome.

Notes on elaboration and simulation when using ghdl

There are three architectures of code generation for ghdl, using a GCC backend, an LLVM back end and an mcode just in time code generator.

From the newest GHDL Documentation section on Invoking GHDL for the run command:

run -r

Runs/simulates a design. The options and arguments are the same as for the elaboration command.

  • GGC/LLVM: simply, the filename of the executable is determined and it is executed. Options are ignored. You may also directly execute the program. The executable must be in the current directory.
  • mcode: the design is elaborated and the simulation is launched. As a consequence, you must use the same options used during analysis.

In an mcode version such as distributed for Win32 the -e elaborate command is redundant and the run command (-r) must include the same options as for the analysis command (-a).

For GCC/LLVM backend codegenerator versions of ghdl the elaborate (-e) command must have the same options as the analysis command (-a). For --std=08 a different working library is used and any object files produced without the std option or with a different STD value will be overwritten if the library directory is not specified separately.

There are no object files for the mcode version. The analyzed objects only exist in the ghdl program's memory where the are subsequently elaborated with the run (-r) command into a simulation design model.

Without specifying versions or release the user can only rely on ghdl documentation.

You could also note that ghdl-0.34 has been released in the last day and a Win32 binary image (mcode) and 64 bit binary image (llvm) are available (their names include "mingw").

其他推荐答案

Your divisions should be integer divisions; they are not (fixed point divisions). And I do not even imagine what the modulus operator is supposed to return when applied to non integer (fixed point) arguments. Anyway, this fixed point representation is quite simple, so, if you just want the digits of the integer part of a positive fixed point number, you could first convert it to natural, and then compute the digits:

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;

Or, if you simply want to print the decimal representation of cp:

use std.textio.all;
...
variable l: line;
...
write(l, to_integer(u_unsigned(cp(20 downto 0)));
writeline(output, n);

Or, even simpler, use the write procedure from the library itself:

variable tmp: sfixed(20 downto 0);
...
tmp := cp(20 downto 0);
write(l, tmp);
writeline(output, l);
相关标签/搜索