#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 является последним символом в строке.