我正在用vhdl读取一个文本文件。这方面有很多例子,但我很好奇为什么这个极小的示例在GHDL中不能工作。It 在ModelSim (由Mentor)中工作。
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中工作。
然而,我仍然不知道为什么以前的版本不起作用。
发布于 2020-04-05 01:13:46
该示例代码预计将失败。注意缺少过程file_close调用。
在执行wait for 100 ns;等待语句之后,流程语句的执行将在未来的模拟周期中恢复。进程中的语句按顺序执行,在最后一个语句(等待语句)之后执行第一个语句。
file_open(input, "input.txt");将再次被处决。
如果没有中间的file_close调用,后续的file_open调用将失败。
IEEE Std 1076-2008
10.2等待语句
超时子句指定进程在这个等待语句中将保持挂起的最长时间。如果没有显示超时子句,则假定超时子句用于(STD.STANDARD.TIME‘High-STD.STANDARD.NOW)。如果timeout子句中的时间表达式计算为负值,则为错误。
11.3过程说明
过程语句的执行由其语句序列的重复执行组成。在执行流程语句序列中的最后一条语句后,将立即继续执行语句序列中的第一条语句。
5.5.2档案操作:
在第二种形式的FILE_OPEN中,通过Status参数返回的值指示过程调用的结果:-A值OPEN_OK表示对FILE_OPEN的调用成功。如果对FILE_OPEN的调用指定了在调用开始时不存在的外部文件,如果传递给调用的文件对象的访问模式是只写的,则创建外部文件。
-值STATUS_ERROR表示文件对象已经具有与其关联的外部文件。
- NAME_ERROR值表示外部文件不存在(在试图从外部文件读取的情况下)或无法创建外部文件(在试图写入或附加到不存在的外部文件时)。如果外部文件由于任何原因无法与文件对象关联,则也返回此值。
-值MODE_ERROR表示无法用请求的Open_Kind打开外部文件。如果第二种形式的FILE_OPEN在相同条件下调用时,将返回OPEN_OK以外的状态值,则第一种形式的OPEN_OK会导致错误发生。
file_open过程调用的问题使用是第一种形式。第二个表单将无法返回状态参数值STATUS_ERROR,该值已经将外部文件与文件对象input关联起来。
解决方法是转换wait语句,以防止进程继续执行:
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
%% 其中,对文件输出(控制台)的写入会回显input.txt中每一行的内容。请注意,通过readline过程调用删除行尾,并将其重新引入到要写入输出的字符串中。
那么为什么不同的文件声明会成功呢?
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.5File声明)。该文件仍然处于打开状态,但没有剩余的行可读取,这是由endfile调用确定的。在这里,端点文件调用将每100 ns发生一次,这很可能导致您的CPU利用率随着测试的执行而增加,直到达到“时间”。执行endfile调用将导致主机文件操作,导致挂起和恢复ghdl模型执行。只进行最终文件过程调用的有效测试。
没有超时子句(for 100 ns)的等待语句(10.2)将等待时间‘高效结束仿真,而不发生任何干扰信号事件或其他进程暂停和恢复,或进行高/100 ns -1结束文件过程调用,每次调用都涉及暂停和恢复显示的进程语句。
还可以在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
%% 主机文件操作可能会导致严重的执行时间损失。如果要将读值分配给复合(数组或记录)类型对象的信号或变量,则可以重用它们,而无需等待主机文件操作。
https://stackoverflow.com/questions/61028754
复制相似问题