如何从 VHDL 中的一行中读取元素?
How to read elements from a line in VHDL?
我正在尝试使用 VHDL 从可能具有不同格式的文件中读取。我知道你应该使用以下两行代码一次读取一行,读取该行中的单个元素。
readline(file, aline);
read(aline, element);
但是我的问题是 read(aline, element)
return 会变成 element
什么?如果该行是空的,它 return 会是什么? return 如果我用了 5 次而我的行只有 4 个字符,它会是什么?
我想知道的原因是,如果我正在读取一个有效数据之间有任意数量 space 的文件,我该如何解析这个有效数据?
该文件包含由任意数量的白色分隔的 ASCII 字符 space(任意数量的 space、制表符或换行符)。如果该行以 # 开头,则该行是注释,应忽略。
除了这些注释之外,文件的第一部分包含的字符只是字母或数字的可变大小组合。换句话说:
123 ABC 12ABB3
但是,文件的大部分(在读取一定数量的单词后)将是任意长度的纯数字,由任意数量的白色分隔 space。也就是说,文件的第二部分是这样的:
255 0 2245 625 430
2222 33 111111
而且我必须能够单独解析这些数字(并这样解释它们)。
如评论中所述,std.textio
和 ieee.std_logic_textio
中的所有 read
过程都会跳过前导 space,除了 character
和 string
版本(因为 space 和其他字符一样多)。
您可以像这样测试 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
中的版本,如果读取不成功,则读取为 non-destructive(即您尝试读取的任何内容都保留在缓冲区中)。但是,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
我正在尝试使用 VHDL 从可能具有不同格式的文件中读取。我知道你应该使用以下两行代码一次读取一行,读取该行中的单个元素。
readline(file, aline);
read(aline, element);
但是我的问题是 read(aline, element)
return 会变成 element
什么?如果该行是空的,它 return 会是什么? return 如果我用了 5 次而我的行只有 4 个字符,它会是什么?
我想知道的原因是,如果我正在读取一个有效数据之间有任意数量 space 的文件,我该如何解析这个有效数据?
该文件包含由任意数量的白色分隔的 ASCII 字符 space(任意数量的 space、制表符或换行符)。如果该行以 # 开头,则该行是注释,应忽略。
除了这些注释之外,文件的第一部分包含的字符只是字母或数字的可变大小组合。换句话说:
123 ABC 12ABB3
但是,文件的大部分(在读取一定数量的单词后)将是任意长度的纯数字,由任意数量的白色分隔 space。也就是说,文件的第二部分是这样的:
255 0 2245 625 430
2222 33 111111
而且我必须能够单独解析这些数字(并这样解释它们)。
如评论中所述,std.textio
和 ieee.std_logic_textio
中的所有 read
过程都会跳过前导 space,除了 character
和 string
版本(因为 space 和其他字符一样多)。
您可以像这样测试 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
中的版本,如果读取不成功,则读取为 non-destructive(即您尝试读取的任何内容都保留在缓冲区中)。但是,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