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

标签 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;

我运行以下 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

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

% od -tx4 out.bin
0000000 7fffffff

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

ghdl:error: overflow detected
    from: ieee.numeric_std.to_integer at numeric_std-body.vhdl:3040
ghdl:error: simulation failed

如上所述,写入操作适用于前 31 位中的任何值。写入将溢出任何设置了 32 位的值。

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

此处接受的答案指出使用中间“文本”格式作为文本处理语言。另一个答案显示了使用 'pos 阅读的解决方案,但这对我写作没有帮助。

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

最佳答案

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

对于 8 位写入,您有责任确保字节顺序正确。

您可以使用专门用于将 32 位无符号值写入字 rune 件的写入过程来做到这一点:

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

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

od -tx4 out.bin
0000000          7fffffff        ffffffff
0000010

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

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

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

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

原始帖子的作者遇到了评论中报告的问题:

The write() above generates an error during analysis:
u32_file_write.vhd:23:14:error: cannot resolve overloading for subprogram call.

The error repeats four times, once for each write(). I've not found a way to get GHDL to write raw bytes other than an integer.

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

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

使用的 ghdl 版本是最新版本 (GHDL 0.36-dev (v0.35-259-g4b16ef4)),使用 AdaCore 2015 GPL gnat (GPL 2015 (20150428-49)) 构建,并使用 llvm 后端进行测试MacOS(10.11.6,gnat-gpl-2015-x86_64-darwin-bin 和 clang+llvm-3.8.0-x86_64-apple-darwin,使用Xcode 8.2.1).

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

关于设置高位时 VHDL/GHDL 二进制 32 位写溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51805144/

相关文章:

vhdl - 写入 avalon 从模块的问题

vhdl - 在 VHDL 中添加两个 bit_vector 返回错误 "(vcom-1581) No feasible entries for infix operator ' +'."

hardware - VHDL 使用数学表达式进行动态切片

VHDL 案例选择不是局部静态的

python - 在cocotb中用ghdl修改VHDL泛型值

unit-testing - 为 VHDL 设计运行多个测试平台

VHDL的rising_edge函数改为使用下降沿?

optimization - 计算结果和多路复用与否

vhdl - VHDL 包 'IEEE.std_logic_arith' 是否随 ghdl 一起提供?