Чтение файла в GHDL / VHDL - PullRequest
       37

Чтение файла в GHDL / VHDL

1 голос
/ 04 апреля 2020

Я работаю над чтением текстового файла в VHDL. Есть много примеров по этому поводу, но мне любопытно, почему этот минимальный демонстрационный пример не работает в GHDL . работает в ModelSim (от 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). Я пробовал это также с полным именем файла.

Я использую GHDL 0.37 на Linux с этими флагами: --ieee=synopsys --std=08

Если

   file input : text;

- это заменен на

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

и

        file_open(input, "input.txt");

удален, он работает в GHDL.

Однако я до сих пор не знаю, почему предыдущая версия не работала.

1 Ответ

3 голосов
/ 05 апреля 2020

Ожидается, что пример кода не удастся. Обратите внимание на отсутствие процедуры 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
%% 

Операции с хост-файлом могут повлечь за собой существенное снижение времени выполнения. Если вам нужно было присвоить считанные значения сигналу или переменной объекта составного типа (массива или записи), их можно использовать повторно, не дожидаясь операций с файлом узла.

...