我有一个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位数据写入二进制文件?
答案 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