首页 > 解决方案 > 关于从行间距的文本中读取的问题

问题描述

我正在尝试编写一个程序,它以十六进制格式逐字节读取长数据行。我能够按预期逐字节读取十六进制格式的数据,但是它有两个问题。

1)我面临的一个小问题是例如:如果正在读取的文本代码是AA BB CC-(将 - 作为额外的字符空间),它将导致代码停止读取字符空间之后的其余行。

2)下一个问题是,如果行之间有额外的空格。例子:

AA BB  
--(paragraph or line spacing in between here)  
CC DD

该程序将在 AA BB 之后停止阅读。您对如何补救有任何想法吗?

对于问题(1),我read(inline, v_SPACE1);在时钟周期后添加了另一行。这似乎在大多数情况下都有效。除了成绩单一直显示 TEXTIO 过程 READ(CHARACTER) :参数 L 指定一个空字符串。希望不要影响以后的阅读。

对于问题(2)我尝试添加 readline(infile, inline); 和另一个while循环,但我想那是行不通的。

--Library used
----
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE IEEE.std_logic_textio.all;
LIBRARY STD;
USE STD.textio.all;
USE IEEE.std_logic_unsigned.all;
USE IEEE.numeric_std.all;
---
--signal used
signal readdatainput : std_logic_vector(7 downto 0);


--variable used
variable v_SPACE1     : character;
variable inline    : line; --line number declaration
file   listfile    : text is in  "list.txt"; --this file is used for a different purpose 
variable inputdata : std_logic_vector(7 downto 0);
file      infile : text;
variable inputdata : std_logic_vector(7 downto 0);
------------------------------------
begin
-
-
-
file_open(infile,inline.ALL,READ_MODE); --inline.ALL refers an earlier part of the program which reads from a text files and gathers the names of files to open
while not endfile(infile) loop   --checking the "END OF FILE" is not reached.
    readline(infile, inline);       --reading a line from the file.
    next when inline(1) = '#'; 
    next when inline(1) = '[';
    while (inline'length /= 0)  loop 
        hread(inline, inputdata);
        readdatainput <= inputdata;
        wait until rising_edge(clock);

        read(inline, v_SPACE1); -- this is my attempt for character space   
    end loop;
end loop;
file_close(infile);  

使用此代码,它将逐字节读取,但是一旦到达行之间的行/段落空间,它将停止读取。

标签: vhdl

解决方案


是的,问题可以解决。

从您的问题来看,您的代码似乎缺少跳过尾随空格或空白行的能力。阅读/阅读等已经有能力跳过前导空白。

代码片段扩展为能够模拟的 VHDL 设计单元,并进行更改以忽略空行和尾随空格:

library ieee;
use std.textio.all;
use ieee.std_logic_1164.all;
use ieee.std_logic_textio.all;

entity reporducable is
    generic ( filename: string := "data.txt");
end entity;

architecture example of reporducable is
    signal clock:           std_logic := '0';
    signal readdatainput:   std_logic_vector (7 downto 0);
begin
some_process:
    process
        variable inline: line;
        file infile: text;
        variable inputdata: std_logic_vector (7 downto 0);
        variable c: character;
    begin
        file_open(infile,filename,READ_MODE);
        while not endfile(infile) loop   
            readline(infile, inline);
            next when inline'length = 0; -- skip empty line
            next when inline(1) = '#'; 
            next when inline(1) = '[';
            while inline.all'length /= 0  loop
                while inline.all'length /= 0 loop  -- eat white space
                    c := inline(inline'left); -- read can modify or deallocate
                    if c = ' ' or c = CR or c = HT then
                        read(inline, c);
                    else
                        exit;
                    end if;
                end loop;
                if inline.all'length = 0 then  -- nothing but eaten white space
                    exit;
                end if;
                hread (inline, inputdata);
                readdatainput <= inputdata;
                wait until rising_edge(clock);  
            end loop;
        end loop;
        file_close(infile); 
        wait; 
    end process;
clock_process:
    process
    begin
        wait for 10 ns;
        clock <= not clock;
        if now > 200 ns then
            report "et fini";
            wait;
        end if;
    end process;
end architecture;

(实体名称reporducable使评论中的 Tricky 拼写错误“reproducible”变得轻而易举。)

对于 data.txt:

# First column
AA BB CC 
DD EE FF 

77 88 99
[ignored]

不显示尾随空格:

od -a data.txt
0000000    #  sp   F   i   r   s   t  sp   c   o   l   u   m   n  nl   A
0000020    A  sp   B   B  sp   C   C  sp  nl   D   D  sp   E   E  sp   F
0000040    F  nl  nl   7   7  sp   8   8  sp   9   9  nl   [   i   g   n
0000060    o   r   e   d   ]  nl
0000066

其中读取行的第一个字符是 # 或 [,或者读取行为空或忽略尾随空格:

可重现的.jpg

使用说明inline(inline'left)

请参阅 IEEE 标准 1076-2008 16.4 包文本:

包 TEXTIO 中声明的每个 READ、SREAD、OREAD 和 HREAD 过程从参数 L 指定的字符串值的开头提取数据,并修改该值,以便它在退出时指定行的剩余部分。每个过程可以在调用开始时修改由参数 L 指定的对象的值,或者可以解除分配对象。

read操作可以使用新对象的分配、前一个对象的复制和释放,或者操作对象的左边界,这要快得多。

根据在 a 期间使用哪种方法更新 Line 值read,索引值 1 可能超出范围,并且始终可以使用 'LEFT 属性检查 a 之后对象的第一个值read以确保可移植性。

readline在没有干预read调用的调用之后使用索引 1 是安全的,这readline是使用分配所必需的,并且read实现选择允许在修剪前导字符时主机系统分配和释放可能效率低下的性能优化。


推荐阅读