尝试在 VHDL 中读取二进制文件时出错

问题描述 投票:0回答:1

我正在尝试编写一个 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)”的定义

vhdl simulation ghdl
1个回答
0
投票

问题在于示例的实现定义存储格式与 data_chA_r00020.bin 的内容不兼容。

解决此问题的一般方法有两种:

  • 您可以将二进制文件外部转换为与 TEXTIO 兼容的文件。
  • 您可以将二进制文件作为字符序列来读取。字符类型是 二进制表示形式,其字节表示形式的所有 256 个值在其声明中定义。

第二个选项取决于几个因素。

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位表示的转换:

read_binary_file.jpg

© www.soinside.com 2019 - 2024. All rights reserved.