Как записать новую строку в файл в VHDL?

#vhdl

#vhdl

Вопрос:

Я хотел бы разделить свои данные new line символом в выходном файле, но следующие коды приводят к ошибке «не удается разрешить перегрузку для вызова процедуры»:

 write(out_line, "n"); 
write(out_line, ""); 
write(out_line, '');
 

Пример кода, как я хочу его использовать:

 ENTITY writer IS 
PORT ( clk : IN STD_LOGIC := '0'; start : IN STD_LOGIC := '0');
END ENTITY;

ARCHITECTURE arch OF writer IS
    SIGNAL vect : STD_LOGIC_VECTOR (2 downto 0) := "000";
    TYPE state_type IS (init, write_file);
    SIGNAL state : state_type := init;
BEGIN
    PROCESS (clk, start)
        FILE out_file : text;
        VARIABLE out_line : line;
    BEGIN
       IF rising_edge(clk) THEN
           CASE state IS 
               WHEN init => 
                   IF start = '1' THEN
                       state <= write_file;
                   ELSE 
                       state <= init;
                   END IF;
               WHEN write_file =>
                   state => init;

                   FOR i IN 0 TO 10 LOOP
                       write(out_line, vect);
                       writeline(out_file, out_line);
                       -- write(out_line, "n"); <-- 
                       -- write(out_line, ""); <-- 
                       -- write(out_line, ''); <-- None of these work
                       writeline(out_file, out_line); 
                   END LOOP;
           END CASE;
       END IF;
   END PROCESS;
END ARCHITECTURE;
               
 

Итак, я хотел бы знать, возможно ли это в VHDL? Если да, то как?

Ответ №1:

Следующее последовательно даст вам одну пустую строку:

 write(out_line, string'(""));  
writeline(out_file, out_line);
 

Я подозреваю, что сообщение @Dani может зависеть от инструмента. Например, в одном популярном симуляторе следующее создает перевод одной строки:

 write(out_line, LF);  
writeline(out_file, out_line);
 

Однако, когда я добавляю пробел после LF, я получаю две строки:

 write(out_line, LF amp; ' ');  
writeline(out_file, out_line);
 

Комментарии:

1. Если исходящая строка не была выделена, освобождена (освободить вызов или строку записи), вы получите пустую строку с последующей строкой записи — «Если параметр L содержит нулевое значение доступа в начале вызова, то в файл или файлы записывается нулевая строка». (То же самое в -1993.) Работает ли это для вашего «одного популярного симулятора»? В предположительно пустой строке не было бы никаких символов. Обратите внимание, что в коде OP, как показано, промежуточные процедуры записи закомментированы и должны выдавать пустую строку для второй процедуры writeline в цикле for . Возможно, использовался «один популярный симулятор»?

Ответ №2:

Создание минимального, полного и проверяемого примера из неполного примера кода вопроса:

 library ieee;  -- ADDED
use ieee.std_logic_1164.all;  -- ADDED
use std.textio.all;  -- ADDED
-- use ieee.std_logic_textio.all;  -- ADDED for revisions earlier than -2008

ENTITY writer IS 
-- PORT ( clk : IN STD_LOGIC := '0'; start : IN STD_LOGIC := '0');
END ENTITY;

ARCHITECTURE arch OF writer IS
    SIGNAL vect : STD_LOGIC_VECTOR (2 downto 0) := "000";
    -- TYPE state_type IS (init, write_file);
    -- SIGNAL state : state_type := init;

BEGIN
    PROCESS -- (clk, start)
        FILE out_file : text;
        VARIABLE out_line : line;
    BEGIN
      file_open(out_file, "some_file", WRITE_MODE);  -- ADDED
       -- IF rising_edge(clk) THEN
--            CASE state IS
--                WHEN init =>
--                    IF start = '1' THEN
--                        state <= write_file;
--                    ELSE
--                        state <= init;
--                    END IF;
--                WHEN write_file =>
--                    state => init;

                   FOR i IN 0 TO 10 LOOP
                       write(out_line, vect);
                       writeline(out_file, out_line);
                       -- write(out_line, "n"); <-- 
                       -- write(out_line, ""); <-- 
                       -- write(out_line, ''); <-- None of these work
                       writeline(out_file, out_line); 
                   END LOOP;
           -- END CASE;
       -- END IF;
       wait;  -- ADDED
   END PROCESS;
END ARCHITECTURE;
 

демонстрирует способ получения пустой строки в выходных данных:

содержимое some_file:

 000

000

000

000

000

000

000

000

000

000

000

 

Второй writeline вызов процедуры выдает пустую строку без промежуточного write вызова процедуры.

Почему это видно в тексте пакета IEEE Std 1076-2008 16.4:

Процедуры READLINE, WRITELINE и TEE, объявленные в пакете TEXTIO, считывают и записывают целые строки файла типа TEXT. Процедура READLINE вызывает чтение следующей строки из файла и возвращает в качестве значения параметра L значение доступа, которое обозначает объект, представляющий эту строку. Если параметр L содержит ненулевое значение доступа в начале вызова, процедура может освободить объект, обозначенный этим значением. Представление строки не содержит представления конца строки. Это ошибка, если файл, указанный при вызове READLINE, не открыт или, если открыт, файл имеет режим доступа, отличный от только для чтения (см. 5.5.2). Каждая из процедур WRITELINE и TEE приводит к тому, что текущая строка, обозначенная параметром L, записывается в файл и возвращается со значением параметра L, обозначающим нулевую строку.Процедура TEE дополнительно приводит к записи текущей строки в выходной файл. Если параметр L содержит нулевое значение доступа в начале вызова, то в файл или файлы записывается нулевая строка. Если параметр L содержит ненулевое значение доступа в начале вызова, процедуры могут освободить объект, обозначенный этим значением. Это ошибка, если файл, указанный при вызове WRITELINE или TEE, не открыт или, если открыт, файл имеет режим доступа, отличный от режима только для записи.

Язык не определяет представление конца строки. Реализация должна позволять записывать в файл все возможные значения типов CHARACTER и STRING . Однако, поскольку реализации разрешено использовать определенные значения типов CHARACTER и STRING в качестве разделителей строк, может оказаться невозможным прочитать эти значения из ТЕКСТОВОГО файла.

Эффектор формата перевода строки (LF), возникающий как элемент строки, записанной в файл типа TEXT, либо с использованием процедуры WRITELINE или TEE, либо с использованием операции ЗАПИСИ, неявно определенной для типа TEXT, интерпретируется реализацией как обозначающий конец строки. Реализация должна преобразовать LF в определенное реализацией представление конца строки.

Для каждой процедуры WRITE, OWRITE и HWRITE после добавления данных к строковому значению, обозначенному параметром L, L обозначает всю строку. Процедура может изменять значение объекта, обозначенного параметром L в начале вызова, или может освободить объект.

Если происходит освобождение out_line , после вызова будет иметь значение null writeline , а в следующем вызове записывается нулевая строка writeline , которая также указывает конец строки.

Если значение объекта, к которому обращается, out_line является нулевым массивом (не имеющим элементов, ограничений индекса 5.3.2.2 и дискретных диапазонов, нулевой строки), сразу после следующего writeline вызова в файл будет записан конец строки.

По сути, ваш пример кода уже содержит один из этих методов записи пустой строки, который зависит от того, используется ли освобождение условно (может).

Варианты allocate() и free() могут быть относительно дорогостоящими с точки зрения времени выполнения, и когда известен размер выделенного объекта и размер его элемента, меньший «выделенный» объект может быть записан в то же пространство объекта, что экономит время моделирования. Представление объекта массива в ядре моделирования может иметь границы, отличные от значения массива, освобождение и перераспределение могут быть зарезервированы для случаев, когда размер объекта превышает ранее выделенный размер или deallocate происходит явный вызов.

Также существует требование, чтобы реализация переводила символ LF в конец строки при записи в файл. Это другой механизм, который позволяет вам записать символ LF в качестве последнего или единственного символа в строке и получить следующую пустую строку.

Вы также можете явно записать нулевую строку в out_line

          write(out_line, string'(""));
 

перед вторым writeline вызовом. Квалифицированное выражение предоставляет тип строкового литерала, в отличие от попытки, прокомментированной в исходном вопросе, где тип строкового литерала не может быть определен. См. раздел 9.3.2 Литералы «… Тип строкового или битового строкового литерала должен определяться исключительно из контекста, в котором появляется литерал, исключая сам литерал, но используя тот факт, что тип литерала должен быть одномерным массивом символьного типа. …». Процедура write была бы неоднозначной в этом контексте, не разрешая перегрузку (12.5 Контекст разрешения перегрузки).

Ответ №3:

Наконец, после долгих поисков и попыток я обнаружил, что работает следующий код:

 write(out_line, lf);  
writeline(out_file, out_line);
 

Я обнаружил, что write(out_line, cr); это делает то же самое и write(out_line, nul); добавляет ' ' символ между выводами.

Комментарии:

1. Авторитетным местом для поиска будет IEEE Std 1076 (здесь -2008) 16.4 Package TEXTIO «Эффектор формата перевода строки (LF), представляющий собой элемент строки, записанной в файл типа TEXT, либо с использованием процедуры WRITELINE или TEE, либо с использованием операции записи, неявно определенной для типа TEXT, интерпретируется реализацией как обозначающий конец строки. Реализация должна преобразовать LF в определенное реализацией представление конца строки .. » LF — это имя перечисления для значения перевода строки (СТАНДАРТ пакета 16.3, объявление типа CHARACTER).

2. @user1155120 Почему я не получаю 2 перевода строки для приведенного выше кода. Один для LF и один для writeline? Например, если бы я вместо этого сделал «write(out_line, lf amp; ‘ ‘);», а затем выполнил строку записи, я бы наверняка получил 2 перевода строки. Я подозреваю, что это связано с тем, что у одного поставщика странное поведение, когда LF является последним символом в строке.