【问题标题】:VHDL - Convert string into a 32 bit integerVHDL - 将字符串转换为 32 位整数
【发布时间】:2020-12-15 11:33:46
【问题描述】:

我有一个文本文件,其中包含计算的预期输出和一个 vhdl 测试台,其中包含一个进行计算的被测模块。这个想法是用文件中的预期输出来计算模块的输出。

该模块在 32 位上工作,文件包含最大 32 位的整数值列表(逐行)。问题是我写了一段代码来比较模块的每个输出和文件的每个输出,但这给了我一个奇怪的错误。

代码是这个:


process

        
        variable line_v : line;
        file read_file : text;
        variable read_int : integer;
        variable read_string: string(1 to 10); --Max integer on 32 bit is 4294967295: 10 chars

begin


        file_open(read_file, "mat2.mem", read_mode);
        for i in 0 to 31 loop
            for j in 0 to 31 loop
                readline(read_file, line_v);
                read(line_v, read_string);
              
                row <= std_logic_vector(TO_UNSIGNED(i, row'length));
                col <= std_logic_vector(TO_UNSIGNED(j, col'length));
                wait for 2 ns; -- after 2 ns, I have the result available on 32 bit std_logic_vector "data"
                
                assert unsigned(data) = integer'value(read_string) report "ERROR! Result not equal to expected one!";
                
            end loop;
        end loop;

        file_close(read_file);

end process;

我收到的错误是这个(根据模拟器数据包含3413424693):

错误:值字符串“3413424693”无法解释为整数类型

我该如何解决这个问题?

谢谢

【问题讨论】:

  • EEE Std 1076-2008 16.2 类型和对象的预定义属性,T'VALUE(X) “限制:如果参数不是 T 类型的文字的有效字符串表示形式或如果结果不属于 T 隐含的子类型。"特定实现中 INTEGER 的范围可从其“低”和“高”属性的值确定。”提供minimal reproducible example。我该如何解决这个问题?考虑包 numeric_bit 或 numeric_std 以及一个输出为无符号类型。输入将是位字符串文字形式的文本字段。
  • Synopsys 包 std_logic_textio 的等效项已合并到各自的 -2008 包 std_logic_1164 和 numeric_std 中。 Synopsys 包 std_logic_textio 和 -2008 numeric_std 包含对无符号类型的读取。在 -2008 位字符串文字中可能有一个十进制基数以及一个长度前缀。否则为二进制、八进制或十六进制。

标签: string file integer vhdl


【解决方案1】:

我该如何解决这个问题?

从 cmets 和其他答案中可以看出,VHDL 中没有定义 32 位无符号整数值范围。如果有,它将依赖于供应商实现且不可移植。无需等待具有 64 位范围整数的 -2019 实现(-2008 迄今为止还没有完整的实现),值得探索其他选项。

似乎有两种基本的解决方法。使用可以读取长度为 32 的 std_logic_vector(或无符号值)或以较小增量处理整数值的读取过程。读取过程解决方案来自 Synopsys 包 std_logic_textio 或 -2008 IEEE 包 numeric_std(无符号)或包 std_logic_1164(std_logic_vector)。这些将要求读取的值是位字符串文字或 1 和 0 的字符串(不是抽象文字)。

可以演示一种处理较小整数的方法。这里的想法是将整数值转换为较小的无符号值,这里是十进制数字,并将所有数学运算作为无符号数。

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

package dec_conv is
    function dec2slv(s: string; l: positive := 32) return std_logic_vector;
end package dec_conv;

package body dec_conv is
    function dec2slv(s: string; l: positive := 32) return std_logic_vector is
        variable decade:    positive := 1;
        variable result:   unsigned (l - 1 downto 0) := (others => '0');
    begin
        for i in s'reverse_range loop
            result := result + resize (
                      (to_unsigned(natural'value("" & s(i)), l) * decade)
                      , l);
            decade := decade * 10;
        end loop;
        return std_logic_vector(result);
    end function;
end package body;

library ieee;
use ieee.std_logic_1164.all;
use work.dec_conv.all;

entity dec2slv_tst is
end entity;

architecture foo of dec2slv_tst is
    signal data:    std_logic_vector (31 downto 0) := x"cb74ba35";
begin
    assert data = dec2slv("3413424693")
        report "ERROR"
        severity ERROR;
end architecture;

该函数可以从由表示数值 0 - 9 的字符组成的任意长度字符串生成任意长度的 std_logic_vector。请注意,没有检查来确定指定长度是否兼容,并且可能会产生错误。长度由l 指定,它有一个默认值(这使得它可以在函数调用中指定)。它适用于您的最大无符号整数值 4294967295,由长度为 32 的向量中的所有“1”表示。

reverse_range 的使用从 LS 数字开始。请注意,此处可以使用字符串输入值的别名来确保s 具有上升范围(字符串类型具有延迟范围)。别名可以指定子类型指示并始终提供上升范围并在子程序主体中用于代替s。 resize 函数调用是将较低的l 长度乘积赋值给resultdecade 用作从右到左每个数字的权重值。

使用此方法的执行工作量与使用读取过程读取位字符串文字(在 -2008 中可以是十进制)大致相当。

【讨论】:

    【解决方案2】:

    如果你查看std.standard 包,你会看到:

    type INTEGER is range -2147483647 to 2147483647;
    

    3413424693 大于 2147483647。因此你的错误。基本上,这个评论是不正确的:

    --Max integer on 32 bit is 4294967295
    

    应该是:

    --Max integer on 32 bit is 2147483647
    

    【讨论】:

    • 另请注意,这不是完整的 32 位范围。 -2^31 不覆盖(最小值为-2^31+1)如果你能找到实现VHDL 2019的工具,那么整数已经增加到64位了。
    • 不太准确。 IEEE Std 1076-2008 5.2.3.2 预定义整数类型“唯一的预定义整数类型是 INTEGER 类型。INTEGER 的范围取决于实现,但保证包括范围 –2147483647 到 +2147483647。它用升序定义范围。” “注意——特定实现中的 INTEGER 范围可根据其 'LOW 和 'HIGH 属性的值确定。” 16.3 包标准“type INTEGER is range implementation_defined;”在保证范围之外存在可移植性问题。
    • ghdl - "整数类型的范围是 -2147483648 到 2147483647;"
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-12-22
    • 2018-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多