高位设置时的 VHDL/GHDL 二进制 32 位写溢出

eso*_*ton 2 vhdl ghdl

我有一个 VHDL 测试平台,我想将 32 位二进制字写入文件进行测试。下面是一个最小的、完整的、可验证的示例。

当使用 GHDL(下面的命令)执行时,会在指定的行产生溢出。如果该行被注释掉,则执行成功完成并写入文件。任何时候设置高位都会发生溢出。

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use std.textio.all;
use std.env.stop;

entity u32_file_write is
end entity;

architecture rtl of u32_file_write is
    type intFileType is file of natural;
    file fh : intFileType;
begin
    run: process
        variable no_high_bit : std_logic_vector(31 downto 0) := x"7FFFFFFF";
        variable with_high_bit : std_logic_vector(31 downto 0) := x"FFFFFFFF";
    begin
        file_open(fh, "out.bin", write_mode);
        write(fh, to_integer(unsigned(no_high_bit)));
        write(fh, to_integer(unsigned(with_high_bit))); -- Overflow here.
        file_close(fh);
        stop;
    end process;
end architecture;
Run Code Online (Sandbox Code Playgroud)

我运行以下 GHDL 命令来运行 VHDL 代码(另存为u32_file_write.vhd):

ghdl -a -fexplicit --std=08 --ieee=synopsys u32_file_write.vhd
ghdl -e -fexplicit --std=08 --ieee=synopsys u32_file_write
ghdl -r -fexplicit --std=08 --ieee=synopsys u32_file_write
Run Code Online (Sandbox Code Playgroud)

注释掉该行后,将更正的结果写入文件:

% od -tx4 out.bin
0000000 7fffffff
Run Code Online (Sandbox Code Playgroud)

如果该行未注释,则会生成溢出:

ghdl:error: overflow detected
    from: ieee.numeric_std.to_integer at numeric_std-body.vhdl:3040
ghdl:error: simulation failed
Run Code Online (Sandbox Code Playgroud)

如上所述,写入将使用前 31 位中的任何值。写入将溢出任何设置 32 位的值。

潜在的问题是 integer'high 是 2^31-1。看:

此处接受的答案声明使用中间“文本”格式文本处理语言。另一个答案显示了使用 'pos 阅读的解决方案,但这并不能帮助我写作。

是否有一个简单的返工/解决方法可以让我将所有 32 位数据写入二进制文件?

小智 5

将您的文件类型更改为字符。一次将 8 位转换为字符并将所有四个字符写入文件,

使用 8 位写入,您负责获得正确的字节序。

您可以使用专为将 32 位无符号值写入字符文件而定制的写入过程来做到这一点:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use std.textio.all;
use std.env.stop;

entity u32_file_write is
end entity;

architecture foo of u32_file_write is
    -- type intFileType is file of natural;  
    type intFileType is file of character;  -- CHANGED type mark
    file fh : intFileType;
    procedure write (file cf: intFileType; val: unsigned (31 downto 0)) is
    begin
        write (cf, character'val(to_integer(val( 7 downto  0))));
        write (cf, character'val(to_integer(val(15 downto  8))));
        write (cf, character'val(to_integer(val(23 downto 16))));
        write (cf, character'val(to_integer(val(31 downto 24))));
    end procedure;
begin
    run: process
        variable no_high_bit : std_logic_vector(31 downto 0) := x"7FFFFFFF";
        variable with_high_bit : std_logic_vector(31 downto 0) := x"FFFFFFFF";

    begin
        file_open(fh, "out.bin", write_mode);
        -- write(fh, to_integer(unsigned(no_high_bit)));
        -- write(fh, to_integer(unsigned(with_high_bit))); -- Overflow here.
        write (fh, unsigned(no_high_bit));
        write (fh, unsigned(with_high_bit));
        file_close(fh);
        stop;
    end process;
end architecture;
Run Code Online (Sandbox Code Playgroud)
ghdl -a -fexplicit --std=08 --ieee=synopsys u32_file_write.vhdl
ghdl -e -fexplicit --std=08 --ieee=synopsys u32_file_write
ghdl -r -fexplicit --std=08 --ieee=synopsys u32_file_write
Run Code Online (Sandbox Code Playgroud)

请注意,除了此处所需的命令(-a、-e、-r)之外,唯一的命令行参数是 --std-08,因为stop. 没有 Synopsys 软件包依赖项,也不需要 -fexplicit(两者都不依赖)。

od -tx4 out.bin
0000000          7fffffff        ffffffff
0000010
Run Code Online (Sandbox Code Playgroud)

主机的文件系统包含由 8 位字符数组组成的文件。惯例(格式)叠加了更大的想法。

VHDL 在文件事务上叠加类型,不幸的是,无法声明大于 2 ** 31 -1 的自然范围值,如果您的整数更大,它们将无法移植。

上述方法将文件视为字符文件,允许按约定叠加内容元素的大小(在主机系统中,如果您想读取 32 位无符号,您需要读取 4 个字符并在正确的字节序)。

这里的 unsigned_int 是一个 32 位无符号值。请注意,由于隐式子类型转换(形式元素和实际元素在此处按从左到右的顺序关联),因此在子程序调用中不需要匹配升序或降序。

原帖作者在评论中遇到了一个问题:

上面的 write() 在分析过程中产生一个错误:
u32_file_write.vhd:23:14:error: cannot resolve Overloading for subprogram call。

该错误重复四次,每次 write() 一次。我还没有找到让 GHDL 写入整数以外的原始字节的方法。

注释中的第 23 行似乎对应于上面的第 18 行,其中字符 14 是第一个 write 过程调用的参数列表,write[file IntFileType, character]这表明 typeIntFileType的类型定义的类型标记的声明尚未更改为 type character。过程调用的签名与隐式声明的文件类型 write 的签名不匹配IntFileType,还注意到行号不匹配。

此答案中提供了完整的代码,以允许从问题中完整复制,这是与使用 .vhdl 后缀命名设计文件并使用上面的命令行一起完成的。

使用的 ghdl 版本是使用 AdaCore 2015 GPL gnat (GPL 2015 (20150428-49)) 构建的最新版本 (GHDL 0.36-dev (v0.35-259-g4b16ef4)) 并使用 llvm 后端代码生成器 ( clang+llvm-3.8.0) 和 MacOS 上的 mcode 代码生成器(10.11.6,gnat-gpl-2015-x86_64-darwin-bin 和 clang+llvm-3.8.0-x86_64-apple-darwin,使用 Xcode 8.2。 1)。

(新写入过程中从 val 写入的字符的od -xt out.bin字节序已颠倒,以匹配 OP 的结果字节顺序)