Ожидается, что пример кода не удастся. Обратите внимание на отсутствие процедуры file_close
call.
После выполнения оператора ожидания wait for 100 ns;
выполнение оператора процесса возобновится в следующем цикле моделирования. Операторы в процессе выполняются по порядку, и после последнего оператора (оператора ожидания) первый оператор
file_open(input, "input.txt");
будет выполнен снова.
Без промежуточного вызова file_close последующий file_open вызов не будет выполнен.
IEEE Std 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 указан внешний файл, который не существует в начале вызова, и если режим доступа к объекту файла, переданному вызову, предназначен только для записи, то создается внешний файл.
- A значение STATUS_ERROR указывает, что с файловым объектом уже связан внешний файл.
- Значение NAME_ERROR указывает, что внешнего файла не существует (в случае попытки чтения из внешнего файла) или внешнего файл не может быть создан (в случае попытки записи или добавления во внешний файл, который не существует). Это значение также возвращается, если внешний файл по какой-либо причине не может быть связан с файловым объектом.
- Значение MODE_ERROR указывает, что внешний файл не может быть открыт с запрошенным Open_Kind.
Первая форма FILE_OPEN вызывает ошибку, если вторая форма FILE_OPEN, при вызове в идентичных условиях, возвращает значение состояния, отличное от OPEN_OK.
Вопрос использования вызова процедуры file_open имеет первую форму. Вторая форма не сможет вернуть значение параметра Status из 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 нс, что, вероятно, приведет к увеличению загрузки вашего ЦП при выполнении теста до достижения TIME'HIGH. Выполнение вызова endfile приведет к операциям с файлом хоста, что приведет к приостановке и возобновлению выполнения модели ghdl. Эффективный тест выполнения только вызовов процедур endfile.
Оператор ожидания (10.2) без условия тайм-аута (for 100 ns
) будет ожидать, пока TIME'HIGH не завершит симуляцию без каких-либо промежуточных сигнальных событий или других приостановок и возобновлений процесса или установки TIME'HIGH / 100 нс - 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
%%
Операции с хост-файлом могут повлечь за собой существенное снижение времени выполнения. Если вам нужно было присвоить считанные значения сигналу или переменной объекта составного типа (массива или записи), их можно использовать повторно, не дожидаясь операций с файлом узла.