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

时间:2018-08-12 02:05:46

标签: 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位数据写入二进制文件?

2 个答案:

答案 0 :(得分:4)

将文件类型更改为字符。一次将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;
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

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

od -tx4 out.bin
0000000          7fffffff        ffffffff
0000010

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

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

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

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

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

  

上面的write()在分析过程中产生错误:
  u32_file_write.vhd:23:14:error:无法解决以下问题的重载   子程序调用。

     

错误重复四次,每次write()一次。   我没有找到一种方法来使GHDL写入原始字节,   整数。

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

此答案中提供了完整的代码,以允许从问题中进行完整复制,这是在使用.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)上的代码生成器(clang + llvm-3.8.0)和mcode代码生成器Xcode 8.2.1)。

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

答案 1 :(得分:0)

如果您绝对不需要输出为二进制,则可以使用VHDL2008标准过程直接编写向量,而无需进行转换:

$ ghdl --version
GHDL 0.36-dev (v0.35-259-g4b16ef4c-dirty) [Dunoon edition]
 Compiled with GNAT Version: GPL 2017 (20170515-63)
 llvm code generator
Written by Tristan Gingold.

Copyright (C) 2003 - 2015 Tristan Gingold.
GHDL is free software, covered by the GNU General Public License.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ cat u32_file_write.vhd
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
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";
        variable l: line;
        file fh: text open write_mode is "out.txt";
    begin
        hwrite(l, no_high_bit);
        writeline(fh, l);
        hwrite(l, with_high_bit);
        writeline(fh, l);
        file_close(fh);
        stop;
    end process;
end architecture;
$ ghdl -a -fexplicit --std=08 u32_file_write.vhd
$ ghdl -e -fexplicit --std=08 u32_file_write
$ ghdl -r -fexplicit --std=08 u32_file_write
simulation stopped @0ms
$ cat out.txt
7FFFFFFF
FFFFFFFF