VDHL固定的解码代码无法正常工作 [英] VDHL sfixed decoding code does not work properly

查看:81
本文介绍了VDHL固定的解码代码无法正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 David Bishop的不动点库在vhdl中进行一些数学运算.我需要将最终值解码为整数.我遵循的方法如下,我确实得到了小数部分的精细值,但十进制值不正确.我找不到问题了.在十进制部分的第一位,两位数字错误. xx 8374.839923 xx 数字始终是错误的.

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.

执行此操作时,我得到 1 74334.738295

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

开始之后,我需要按固定方式解码174334.738295,因为有时我会得到负数.此数字将由另一个计算(此处未提供)代替,如果该数字为174334.738295(固定),则我需要对该数字进行解码,

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是第一位,L5是第二位.

L6 is the 1st digit and L5 is the 2nd digit.

推荐答案

使用div10,mod10(带下划线的声明不加修饰)的修补程序修改原始代码并生成MCVE:

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:

...获取174334.738295的274334.738295

...get 274334.738295 for 174334.738295

您可以证明to_integer舍入导致L5为2而不是1:

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

因此,所有这些都告诉您仅使用L6-L1的整数部分,因此不进行舍入. (在您评论过的David Bishop的用户指南中,有一个提示提示如何剪切固定或固定的值.)

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.

使用ghdl时的制作和仿真注意事项

ghdl的代码生成有三种架构,它们使用GCC后端,LLVM后端和mcode即时代码生成器.

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.

来自最新的 GHDL文档部分href ="http://ghdl.readthedocs.io/en/new-documentation-structure/using/InvokingGHDL.html" rel ="nofollow noreferrer">为运行命令调用GHDL :

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

运行-r

运行/模拟设计.选项和参数与 细化命令.

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

  • GGC/LLVM:简单地,确定可执行文件的文件名并执行它.选项将被忽略.您也可以直接执行 该程序.可执行文件必须位于当前目录中.
  • mcode:详细设计并启动仿真.因此,您必须使用分析期间使用的相同选项.
  • 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.

在诸如Win32发行版的mcode版本中,-e elaborate命令是多余的,并且运行命令(-r)必须包含与分析命令(-a)相同的选项.

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

对于ghdl的GCC/LLVM后端代码生成器版本,精巧的(-e)命令必须具有与分析命令(-a)相同的选项.对于--std=08,将使用其他工作库,并且如果未单独指定库目录,则不带std选项或具有不同STD值的任何目标文件都将被覆盖.

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.

没有适用于mcode版本的目标文件.被分析的对象仅存在于ghdl程序的内存中,随后使用run(-r)命令将其详细化为仿真设计模型.

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.

未指定版本或发布用户只能依靠ghdl文档.

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

您还可能注意到 ghdl-0.34 已发布在最后一天,将提供Win32二进制映像(mcode)和64位二进制映像(llvm)(它们的名称包括"mingw").

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").

这篇关于VDHL固定的解码代码无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆