如何在 VHDL 中向文件写入新行?

How to write new line to file in 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中是否可行?如果是,如何?

经过大量搜索和尝试,我终于发现以下代码有效:

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

我发现 write(out_line, cr); 做同样的事情,write(out_line, nul); 在输出之间添加 ' ' 字符。

以下将始终为您提供一个空白行:

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

我怀疑@Dani 发布的内容可能与工具有关。例如,在一个流行的模拟器上,以下会产生一个换行符:

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

然而,当我在 LF 后添加 space 时,我得到两行:

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

从问题的不完整示例代码中创建一个最小的、完整的和可验证的示例:

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 Package TEXTIO 中出现:

Procedures READLINE, WRITELINE, and TEE declared in package TEXTIO read and write entire lines of a file of type TEXT. Procedure READLINE causes the next line to be read from the file and returns as the value of parameter L an access value that designates an object representing that line. If parameter L contains a non-null access value at the start of the call, the procedure may deallocate the object designated by that value. The representation of the line does not contain the representation of the end of the line. It is an error if the file specified in a call to READLINE is not open or, if open, the file has an access mode other than read-only (see 5.5.2). Procedures WRITELINE and TEE each cause the current line designated by parameter L to be written to the file and returns with the value of parameter L designating a null string. Procedure TEE additionally causes the current line to be written to the file OUTPUT. If parameter L contains a null access value at the start of the call, then a null string is written to the file or files. If parameter L contains a non-null access value at the start of the call, the procedures may deallocate the object designated by that value. It is an error if the file specified in a call to WRITELINE or TEE is not open or, if open, the file has an access mode other than write-only.

The language does not define the representation of the end of a line. An implementation shall allow all possible values of types CHARACTER and STRING to be written to a file. However, as an implementation is permitted to use certain values of types CHARACTER and STRING as line delimiters, it might not be possible to read these values from a TEXT file.

A line feed (LF) format effector occurring as an element of a string written to a file of type TEXT, either using procedure WRITELINE or TEE, or using the WRITE operation implicitly defined for the type TEXT, is interpreted by the implementation as signifying the end of a line. The implementation shall transform the LF into the implementation-defined representation of the end of a line.

...

For each WRITE, OWRITE, and HWRITE procedure, after data is appended to the string value designated by the parameter L, L designates the entire line. The procedure may modify the value of the object designated by the parameter L at the start of the call or may deallocate the object.

如果发生释放 out_line 将在 writeline 调用后具有空值,并且在紧随其后的 writeline 调用中写入空字符串,该调用还提供行尾.

如果 out_line 访问的对象值是一个空数组(没有元素,5.3.2.2 索引约束和离散范围,一个空字符串)紧接着的 writeline 调用将导致正在写入文件的行尾。

本质上,您的代码示例已经包含这些用于写入空行的方法之一,这取决于是否有条件地(可能)使用释放。

allocate() 和 free() 的变体在执行时间方面可能相对昂贵,并且当分配对象的大小及其元素大小已知时,可以将较小的 'allocated' 对象写入同一对象 space 节省模拟时间。数组对象的模拟内核表示可以具有与数组值分开的边界,当对象大小大于先前分配的大小或发生显式 deallocate 调用时,可以保留释放和重新分配。

还有一个要求,即实现将 LF 字符转换为写入文件时的行尾。这是另一种机制,允许您将 LF 字符作为最后一个或唯一的字符写入一行并获得后续空白行。

您也可以显式地将空字符串写入 out_line

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

在第二次 writeline 调用之前。与无法确定字符串文字类型的原始问题中注释掉的尝试不同,限定表达式提供了字符串文字的类型。见 9.3.2 文字“......字符串或位串文字的类型应仅从文字出现的上下文中确定,不包括文字本身,但使用文字类型应为一个的事实 -字符类型的维数组。...”。过程 write 在这种情况下会产生歧义,导致重载决议失败(12.5 重载决议的上下文)。