【问题标题】:How to read elements from a line in VHDL?如何从 VHDL 中的一行中读取元素?
【发布时间】:2017-01-24 22:11:08
【问题描述】:

我正在尝试使用 VHDL 从可以具有不同格式的文件中读取。我知道您应该使用以下两行代码一次读取一行,读取该行中的各个元素。

readline(file, aline);
read(aline, element);

但是我的问题是read(aline, element) 会返回到element 什么?如果该行为空,它将返回什么?如果我使用了 5 次并且我的行只有 4 个字符,它会返回什么?

我想知道的原因是,如果我正在读取一个在有效数据之间有任意数量空格的文件,我该如何解析这些有效数据?

该文件包含由任意数量的空白(任意数量的空格、制表符或新行)分隔的 ASCII 字符。如果该行以 # 开头,则该行是注释,应被忽略。

在这些 cmets 之外,文件的第一部分包含只有字母或数字的可变大小组合的字符。换句话说:

123           ABC   12ABB3 

但是,文件的大部分内容(在一定数量的读取字之后)将是纯任意长度的数字,由任意数量的空格分隔。换句话说,文件的第二部分是这样的:

255 0       2245   625         430
2222  33        111111

而且我必须能够单独解析这些数字(并解释它们)。

【问题讨论】:

  • 参见 IEEE Std 1076-2008 16.4 包 TEXTIO,第 8 段(部分)为除 CHARACTER 和 STRING 之外的给定类型定义的 READ 过程以跳过前导空白字符开始。空白字符定义为空格、不间断空格或水平制表符(SP、NBSP 或 HT)。对于所有 READ 过程,然后从 L 中删除字符并组合成指定类型值的字符串表示形式(参见 5.7)。
  • 如何在线访问?
  • 是的,我查看了如何通过 IEEE 购买它,但我买不起。不应该免费提供一种语言的参考手册吗?这有点荒谬。

标签: file-io vhdl


【解决方案1】:

正如 cmets 中所述,std.textioieee.std_logic_textio 中的所有 read 过程都会跳过除 characterstring 版本之外的前导空格(因为空格与其他任何字符一样多)。

您可以像这样测试line 变量(缓冲区)是否为空:

if L'length > 0 then

其中L 是您的line 变量。还有一组带有额外状态输出的重载read 过程:

procedure read (L    : inout LINE;
                VALUE: out   <type> ;
                GOOD : out   BOOLEAN);

如果读取成功,额外输出 - GOOD - 是 true,如果不成功,则为 false。如果读取不成功,则这些的优点是模拟不会停止(与常规过程一样)。此外,对于std.textio 中的版本,如果读取不成功,则读取是非破坏性的(即,您尝试读取的任何内容都保留在缓冲区中)。但是,ieee.std_logic_textio 中的版本并非如此。

如果你真的不知道你想读什么格式,你可以把整行读成一个字符串,像这样:

variable S : string(1 to <some big number>);
...
readline(F, L);
assert L'length < S'length;  -- make sure S is big enough
S := (others => ' '); -- make sure that the previous line is overwritten
if L'length > 0 then
  read(L, S(1 to L'length);
end if;

L 行现在位于字符串S 中。然后,您可以编写一些代码来解析它。您可能会发现 type 属性 'value 很有用。这会将字符串转换为某种类型,例如

variable I : integer;
...
I := integer'value(S(12 to 14));

将整数 I 设置为字符串 S 的第 12 到 14 个元素中包含的值。

下面的 user1155120 建议的另一种方法是查看缓冲区中的值,例如

if L'length > 0 then  -- check that the L isn't empty, otherwise the next line blows up
  if L.all(1) = '#' then
    -- the first character of the line is a '#' so the line must be a comment

【讨论】:

  • 非常感谢您的回复!那么我怎么知道要为我的变量设置什么类型呢?我希望能够忽略空白字符,但同时并非我阅读的每一行都只有由空白分隔的数字(尽管其中大多数都是)。换句话说,我正在读取一个具有可变格式的文件。该文件可能包含 cmets(以 # 字符开头的行),并且该文件在极少数情况下也可能包含字母。大多数情况下,该文件由数字组成,并由任意数量的空格分隔。
  • 您的评论表明您的问题不清楚。您暗示可以对 aline 访问的值进行解析(表征行)。 8.3 选择名称对于用于表示访问值指定的对象的选择名称,后缀应为保留字all。前缀应属于访问类型。您可以忽略以“#”开头的行或以其他方式表征行的内容。
  • 对不起,我想问的是我如何知道将传递给 read() 函数的变量设置为什么类型?鉴于我描述的文件的组成,我希望能够解析由空格分隔的元素,但知道这些元素可能不是同一类型。如果我使用read(aline, element),我应该将变量元素设为什么类型?
  • 顺便说一句,我真诚地感谢您的回复,我有一个作业要在星期一完成,占我成绩的 20%,而且班上没有知道 VHDL 的助教或教授,所以我们完全靠自己。
  • 我认为我唯一的选择是单独读取每个字符并根据我要如何解析数据来决定如何处理它?
猜你喜欢
  • 1970-01-01
  • 2017-04-03
  • 1970-01-01
  • 2023-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-04
  • 2016-09-27
相关资源
最近更新 更多