0

我正在阅读 vhdl 中的文本文件。这方面有很多例子,但我很好奇为什么这个最小的展示示例在 GHDL 中不起作用。它在 ModelSim (by Mentor)中工作。

  1. 这是因为 GHDL 中缺少功能吗?(我在 docs/github 问题中没有找到任何内容)
  2. 这是因为我在不知道的情况下使用了错误的标准吗?
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use STD.textio.all;

entity test is
end test;

architecture behavioral of test is
    file input : text;
begin
    process
    variable line_in : line;
    begin
        file_open(input, "input.txt");
        while not endfile(input) loop
            readline(input, line_in); 
        end loop;
        wait for 100 ns;
    end process;

end behavioral;

我得到的输出是:

./test:error: cannot open file "input.txt"

这意味着,没有文件/无法打开,但文件存在并具有正确的访问权限(在 Modelsim 中得到证明)。我也用完整的文件名试过这个。

我在 Linux 上使用带有这些标志的 GHDL 0.37: --ieee=synopsys --std=08

如果

   file input : text;

被替换为

    file input : text open read_mode is "input.txt";

        file_open(input, "input.txt");

被删除它在 GHDL 中工作。

但是,我仍然不知道为什么以前的版本不起作用。

4

1 回答 1

3

示例代码预计会失败。请注意缺少过程file_close调用。

wait for 100 ns;等待语句执行之后,进程语句的执行将在未来的模拟周期中恢复。进程中的语句按顺序执行,在最后一条语句(等待语句)之后是第一条语句

        file_open(input, "input.txt");

将再次执行。

如果没有介入的 file_close 调用,后续的 file_open 调用将失败。

IEEE 标准 1076-2008

10.2 等待语句

timeout 子句指定进程将在此等待语句处保持挂起的最长时间。如果没有出现超时子句,则假定为 (STD.STANDARD.TIME'HIGH – STD.STANDARD.NOW) 的超时子句。如果 timeout 子句中的时间表达式的计算结果为负值,则会出错。

11.3 过程声明

流程语句的执行包括重复执行其语句序列。在执行流程语句的语句序列中的最后一条语句后,将立即继续执行语句序列中的第一条语句。

5.5.2 文件操作:

在第二种形式的 FILE_OPEN 中,通过 Status 参数返回的值表示过程调用的结果:

— OPEN_OK 值表示对 FILE_OPEN 的调用成功。如果对 FILE_OPEN 的调用指定了在调用开始时不存在的外部文件,并且如果传递给调用的文件对象的访问模式是只写的,则创建外部文件。
— STATUS_ERROR 的值表示文件对象已经有一个与之关联的外部文件。
— NAME_ERROR 的值表示外部文件不存在(在尝试从外部文件读取的情况下)或无法创建外部文件(在尝试写入或附加到外部文件的情况下)不存在)。如果外部文件因任何原因无法与文件对象关联,也会返回此值。
— MODE_ERROR 的值表示无法使用请求的 Open_Kind 打开外部文件。

如果在相同条件下调用第二种形式的 FILE_OPEN 时,会返回除 OPEN_OK 之外的状态值,则第一种形式的 FILE_OPEN 会导致错误发生。

file_open 过程调用的问题使用属于第一种形式。第二种形式将无法返回状态参数值 STATUS_ERROR,已经将外部文件与文件对象相关联input

解决方法是转换等待语句以防止进程继续执行:

        wait; -- wait for 100 ns;
    end process;

或提供显式的 file_close 调用,以便后续的 file_open 调用会成功。(这会导致大量主机活动而无用。)

修改后的代码可能如下所示:

-- library IEEE;
-- use IEEE.STD_LOGIC_1164.all;  -- NOT USED
use STD.textio.all;

entity test is
end test;

architecture behavioral of test is
    file input : text;
begin
    process
    variable line_in : line;
    begin
        file_open(input, "input.txt");
        while not endfile(input) loop
            readline(input, line_in);
            write (OUTPUT, line_in.all & LF);
        end loop;
        wait; -- wait for 100 ns;  -- EXECUTE ONCE
    end process;

end behavioral;

产量:

%% ghdl -a --ieee=synopsys  --std=08 test.vhdl
%% ghdl -e --ieee=synopsys  --std=08 test
%% ghdl -r --std=08 test
some text
more text
yet some more text
getting boring
%% 

对文件 OUTPUT(控制台)的写入会回显input.txt. 请注意,行尾被 readline 过程调用删除并重新引入到正在写入 OUTPUT 的字符串中。

那么为什么不同的文件声明会成功呢?

architecture file_declaration of test is
    -- file input : text;
    file input:     text open read_mode is "input.txt";
begin
    process
    variable line_in:   line;
    begin
        -- file_open(input, "input.txt");
        while not endfile(input) loop
            readline(input, line_in);
            write (OUTPUT, line_in.all & LF);
        end loop;
        wait for 100 ns;
    end process;

end architecture file_declaration;

只有一次对 file_open 的调用,这是在详细说明文件声明(6.4.2.5 文件声明)期间的隐式调用。该文件保持打开状态,但没有剩余的行可读取,由 endfile 调用确定。这里的 endfile 调用将每 100 ns 发生一次,这可能会导致您的 CPU 利用率随着测试的执行而增加,直到达到 TIME'HIGH。执行 endfile 调用将导致主机文件操作导致暂停和恢复 ghdl 模型执行。仅进行 endfile 过程调用的有效测试。

没有超时子句 ( ) 的等待语句 (10.2)for 100 ns将等到 TIME'HIGH 有效结束模拟,没有任何干预信号事件或其他进程暂停和恢复或进行 TIME'HIGH/100 ns - 1 个 endfile 过程调用,每个都涉及暂停并恢复显示的过程语句。

您还可以在 ghdl 的命令行上指定模拟停止时间,最有可能与 Modelsim 中的用法相匹配:

%% ghdl -a --ieee=synopsys  --std=08 test.vhdl
%% ghdl -e --ieee=synopsys  --std=08 test
%% ghdl -r --std=08 test --stop-time=300ns
some text
more text
yet some more text
getting boring
./test:info: simulation stopped by --stop-time @300ns
%% 

主机文件操作可能会导致显着的执行时间损失。如果您要将读取的值分配给复合(数组或记录)类型对象的信号或变量,则可以重用它们而无需等待主机文件操作。

于 2020-04-05T01:13:46.020 回答