我正在尝试编写一个 VHDL 模拟模块,该模块读取包含 16 位输入样本的二进制文件。代码如下:
library ieee;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use std.textio.all;
entity read_binary_file is
generic ( clk_per : time := 8 ns );
end read_binary_file;
architecture behav of read_binary_file is
subtype sample is signed(15 downto 0);
type sample_file is file of sample;
file input_file : sample_file;
signal input : signed(15 downto 0);
begin
read_file : process
variable input_data : sample;
begin
file_open(input_file, ".\HPGex2_Na22\data_chA_r00020.bin", read_mode);
while not endfile(input_file) loop
read(input_file, input_data);
input <= input_data;
wait for clk_per;
end loop;
if endfile(input_file) then
file_close(input_file);
wait;
end if;
end process;
end behav;
对于以下命令,我得到以下输出:
ghdl -a“--std=08”./read_binary_file/read_binary_file.vhdl
ghdl -e“--std=08”读取二进制文件
ghdl -r "--std=08" read_binary_file --stop-time="1000ms" --vcd=wave.vcd --disp-time
。 ead_binary_file.exe:内部错误:文件:IO 错误
。 ead_binary_file.exe:错误:模拟失败
我注意到用“整数”、“位”或任何非向量类型(std_logic_vector、signed、unsigned 等)替换样本类型“signed (WIDTH downto 0)”的定义
问题在于示例的实现定义存储格式与 data_chA_r00020.bin 的内容不兼容。
解决此问题的一般方法有两种:
第二个选项取决于几个因素。
ISO/IEC 8859-1:1998,信息技术 — 8 位单字节编码图形字符集 — 第 1 部分:拉丁字母 No. 1 定义了实现所有 256 个值所需的枚举字符类型 CHARACTER 的值。 ghdl 将所有预定义或 IEEE 枚举类型实现为字节。因为不能保证另一个(供应商)实现使用字节,所以可能存在可移植性问题。然而,CHARACTER 的任何实现都可能使用字节来保存它的值。没有计划支持更大的字符集。
VHDL 标准 (IEEE Std 1076-2008) 未定义实现细节。从历史上看,您可以在任何计算机平台上实现 Ada 或 VHDL,包括使用二进制编码的十进制算术的平台,因为算术运算有其数学含义。实现不会透露模拟内核空间中有多少位或结构。
VHDL 确实允许在此处重载子程序 READ 过程读取两个字符,将其位置值转换为二进制表示形式并返回有符号值。按顺序获取两个连续字符(此处为字节)并构造 16 位样本数据值可能会出现问题。这取决于子类型样本的哪个字节被索引为 0 或 1。这取决于目标平台。
字符字节到样本子类型的转换发生在 READ 过程重载中:
library ieee;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
-- use std.textio.all;
entity read_binary_file is
generic ( clk_per : time := 8 ns );
end read_binary_file;
architecture behav of read_binary_file is
subtype sample is signed(15 downto 0);
-- type sample_file is file of sample;
type sample_file is file of CHARACTER;
file input_file : sample_file;
signal input : signed(15 downto 0);
-- OVERLOAD added:
procedure READ (file f: sample_file; ivalue: out sample) is
variable retval: unsigned (sample'range);
variable read_char: CHARACTER;
begin
read (f, read_char);
-- LITTLE ENDIAN:
retval( 7 downto 0) := to_unsigned(CHARACTER'POS(read_char), 8);
read (f, read_char);
retval(15 downto 8) := to_unsigned(CHARACTER'POS(read_char), 8);
ivalue := signed(retval);
end procedure;
begin
read_file:
process
variable input_data : sample;
begin
-- file_open(input_file, ".\HPGex2_Na22\data_chA_r00020.bin", read_mode); -- ORIGINAL
file_open(input_file, "./x29.bin", read_mode);
while not endfile(input_file) loop
read(input_file, input_data);
input <= input_data;
wait for clk_per;
end loop;
if endfile(input_file) then
file_close(input_file);
wait;
end if;
end process;
end behav;
注意,这不依赖于 TEXTIO,它不能用于转换二进制表示,是面向行的,并且不保证行结束指示作为读取字节流的一部分返回。
上面的例子可以演示字符(字节)到16位表示的转换: