VHDL textio,从文件中读取图像
VHDL textio, reading image from file
我正在尝试学习如何在 FPGA 中实现图像处理算法,为此我正在处理一个包含 bmp 图像(使用 MATLAB 转换)的 txt 文件。
我在使用 textio 包时遇到问题,所以现在我只能读取第一列数据(但不能读取整行数据)。
txt文件有这个方面:
1,1,0,0,0
0,1,1,1,1
1,0,0,0,0
0,0,1,1,0
1,1,1,1,1
一个用逗号分隔的 5x5 矩阵。
我现在在模拟中拥有的实体的输出是
1 0 1 0 1
对应第一列。
我不明白为什么代码不读取所有行并且在它结束时跳转到下一行。
这是读取文件的过程(我添加了一个名为逗号的变量,这样我就可以检测到逗号并跳过它,但仍然不起作用):
reading : process
constant filename : string := "C:\DOCUMENTACION\PROYECTOS\Envio_salida_VGA_atraves_FPGA\MatLab\Procesado de imagen con Toolbox\prueba.txt";
file f : text open read_mode is filename;
variable L : line;
variable data_read : integer;
variable comma : character;
begin
while not endfile(f) loop
wait until rising_edge(clk);
readline(f, L);
read(L, data_read);
while L = ',' loop
read(L, comma);
end loop;
d_out <= data_read;
end loop;
我的代码有什么问题?
L 是一个指向字符串的指针。要取消引用指针,您需要:
L.all
因此,要获得角色,您可以这样做:
L.all(1) = ','
作为 shorthand,您还可以:
L(1) = ','
我不明白为什么代码不读取所有行,当它结束时跳转到下一行。
您只是尝试读取一个整数,然后在下一个整数之前读取一个逗号 readline
。
另请注意,只要您可以指望一个字符分隔一行中的连续整数,您就不必关心该字符是什么(而且您根本不用看 comma
) .
要读取一行中的每个整数,您需要注意您的 read
调用是否消耗了所有行缓冲区。
我修改了您的代码,以便在将您的示例数据保存到名为 prueba.txt:
的文件后进行演示
library ieee;
use ieee.std_logic_1164.all;
use std.textio.all;
entity prueba is
end entity;
architecture foo of prueba is
signal d_out: integer;
signal clk: std_logic := '0';
begin
reading:
process
constant filename: string := "prueba.txt";
file f: text open read_mode is filename;
variable L: line;
variable data_read: integer;
variable char: character;
variable len: integer;
begin
while not endfile(f) loop
readline(f, L);
len := L'length;
while len > 0 loop
read (L, data_read);
len := L'length;
if len > 0 then
read (L, char);
len := L'length;
end if;
wait until rising_edge(clk);
d_out <= data_read;
report "data_read = " & integer'image(data_read);
end loop;
end loop;
wait until rising_edge(clk);
wait;
end process;
CLOCK:
process
begin
wait for 5 ns;
clk <= not clk;
if Now > 250 ns then -- picked by prueba.txt number of elements
wait;
end if;
end process;
end architecture;
因为生成的波形需要您计算时钟或时间而不是数据,所以我添加了一个报告语句,它给出:
prueba.vhdl:33:17:@5ns:(report note): data_read = 1
prueba.vhdl:33:17:@15ns:(report note): data_read = 1
prueba.vhdl:33:17:@25ns:(report note): data_read = 0
prueba.vhdl:33:17:@35ns:(report note): data_read = 0
prueba.vhdl:33:17:@45ns:(report note): data_read = 0
prueba.vhdl:33:17:@55ns:(report note): data_read = 0
prueba.vhdl:33:17:@65ns:(report note): data_read = 1
prueba.vhdl:33:17:@75ns:(report note): data_read = 1
prueba.vhdl:33:17:@85ns:(report note): data_read = 1
prueba.vhdl:33:17:@95ns:(report note): data_read = 1
prueba.vhdl:33:17:@105ns:(report note): data_read = 1
prueba.vhdl:33:17:@115ns:(report note): data_read = 0
prueba.vhdl:33:17:@125ns:(report note): data_read = 0
prueba.vhdl:33:17:@135ns:(report note): data_read = 0
prueba.vhdl:33:17:@145ns:(report note): data_read = 0
prueba.vhdl:33:17:@155ns:(report note): data_read = 0
prueba.vhdl:33:17:@165ns:(report note): data_read = 0
prueba.vhdl:33:17:@175ns:(report note): data_read = 1
prueba.vhdl:33:17:@185ns:(report note): data_read = 1
prueba.vhdl:33:17:@195ns:(report note): data_read = 0
prueba.vhdl:33:17:@205ns:(report note): data_read = 1
prueba.vhdl:33:17:@215ns:(report note): data_read = 1
prueba.vhdl:33:17:@225ns:(report note): data_read = 1
prueba.vhdl:33:17:@235ns:(report note): data_read = 1
prueba.vhdl:33:17:@245ns:(report note): data_read = 1
我们发现 prueba.txt 中的所有整数都被读取了。
注意我添加了一个名为 len
的变量来保存 L
中可用的字符数。每个 read
或每个 readline
len
都会更新。如果行中没有更多字符,我们就不会尝试读取。
CLOCK
过程中对Now
的求值和reading
过程中额外的wait until rising_edge(clk);
及后面的wait
只是为了停止模拟波形在哪里有用。
我们使用 L'length
来告诉我们一行中是否还有更多数据,或者我们是否应该掉到外部 while loop
中,如果不在文件末尾则调用 readline
。
您还可以注意到仅使用 'length
属性即可重写该过程:
reading:
process
constant filename: string := "prueba.txt";
file f: text open read_mode is filename;
variable L: line;
variable data_read: integer;
variable char: character;
begin
while not endfile(f) loop
readline(f, L);
while L'length > 0 loop
read (L, data_read);
if L'length > 0 then
read (L, char);
end if;
wait until rising_edge(clk);
d_out <= data_read;
report "data_read = " & integer'image(data_read);
end loop;
end loop;
wait until rising_edge(clk);
wait;
end process;
这给出了相同的答案。如果我们要做一些聪明的事情,比如扔掉评论,我们会使用 len
变量,这也需要我们扫描 L
和 trim 尾随白色 space。我们可以为 len
赋值,但不能为 L'length
赋值。因为在您的 prueba.txt 中没有尾随最后一个数据的内容,所以我们可以简单地使用 length
属性。
您可以研究这个包,它包含最多 3 个维度的动态大小数组类型,可以 load/save from/to csv 和原始文件。
https://github.com/LarsAsplund/vunit/blob/master/vhdl/array/src/array_pkg.vhd
它是 VUnit VHDL 测试框架的一部分。
我正在尝试学习如何在 FPGA 中实现图像处理算法,为此我正在处理一个包含 bmp 图像(使用 MATLAB 转换)的 txt 文件。
我在使用 textio 包时遇到问题,所以现在我只能读取第一列数据(但不能读取整行数据)。
txt文件有这个方面:
1,1,0,0,0
0,1,1,1,1
1,0,0,0,0
0,0,1,1,0
1,1,1,1,1
一个用逗号分隔的 5x5 矩阵。 我现在在模拟中拥有的实体的输出是
1 0 1 0 1
对应第一列。 我不明白为什么代码不读取所有行并且在它结束时跳转到下一行。
这是读取文件的过程(我添加了一个名为逗号的变量,这样我就可以检测到逗号并跳过它,但仍然不起作用):
reading : process
constant filename : string := "C:\DOCUMENTACION\PROYECTOS\Envio_salida_VGA_atraves_FPGA\MatLab\Procesado de imagen con Toolbox\prueba.txt";
file f : text open read_mode is filename;
variable L : line;
variable data_read : integer;
variable comma : character;
begin
while not endfile(f) loop
wait until rising_edge(clk);
readline(f, L);
read(L, data_read);
while L = ',' loop
read(L, comma);
end loop;
d_out <= data_read;
end loop;
我的代码有什么问题?
L 是一个指向字符串的指针。要取消引用指针,您需要:
L.all
因此,要获得角色,您可以这样做:
L.all(1) = ','
作为 shorthand,您还可以:
L(1) = ','
我不明白为什么代码不读取所有行,当它结束时跳转到下一行。
您只是尝试读取一个整数,然后在下一个整数之前读取一个逗号 readline
。
另请注意,只要您可以指望一个字符分隔一行中的连续整数,您就不必关心该字符是什么(而且您根本不用看 comma
) .
要读取一行中的每个整数,您需要注意您的 read
调用是否消耗了所有行缓冲区。
我修改了您的代码,以便在将您的示例数据保存到名为 prueba.txt:
的文件后进行演示library ieee;
use ieee.std_logic_1164.all;
use std.textio.all;
entity prueba is
end entity;
architecture foo of prueba is
signal d_out: integer;
signal clk: std_logic := '0';
begin
reading:
process
constant filename: string := "prueba.txt";
file f: text open read_mode is filename;
variable L: line;
variable data_read: integer;
variable char: character;
variable len: integer;
begin
while not endfile(f) loop
readline(f, L);
len := L'length;
while len > 0 loop
read (L, data_read);
len := L'length;
if len > 0 then
read (L, char);
len := L'length;
end if;
wait until rising_edge(clk);
d_out <= data_read;
report "data_read = " & integer'image(data_read);
end loop;
end loop;
wait until rising_edge(clk);
wait;
end process;
CLOCK:
process
begin
wait for 5 ns;
clk <= not clk;
if Now > 250 ns then -- picked by prueba.txt number of elements
wait;
end if;
end process;
end architecture;
因为生成的波形需要您计算时钟或时间而不是数据,所以我添加了一个报告语句,它给出:
prueba.vhdl:33:17:@5ns:(report note): data_read = 1
prueba.vhdl:33:17:@15ns:(report note): data_read = 1
prueba.vhdl:33:17:@25ns:(report note): data_read = 0
prueba.vhdl:33:17:@35ns:(report note): data_read = 0
prueba.vhdl:33:17:@45ns:(report note): data_read = 0
prueba.vhdl:33:17:@55ns:(report note): data_read = 0
prueba.vhdl:33:17:@65ns:(report note): data_read = 1
prueba.vhdl:33:17:@75ns:(report note): data_read = 1
prueba.vhdl:33:17:@85ns:(report note): data_read = 1
prueba.vhdl:33:17:@95ns:(report note): data_read = 1
prueba.vhdl:33:17:@105ns:(report note): data_read = 1
prueba.vhdl:33:17:@115ns:(report note): data_read = 0
prueba.vhdl:33:17:@125ns:(report note): data_read = 0
prueba.vhdl:33:17:@135ns:(report note): data_read = 0
prueba.vhdl:33:17:@145ns:(report note): data_read = 0
prueba.vhdl:33:17:@155ns:(report note): data_read = 0
prueba.vhdl:33:17:@165ns:(report note): data_read = 0
prueba.vhdl:33:17:@175ns:(report note): data_read = 1
prueba.vhdl:33:17:@185ns:(report note): data_read = 1
prueba.vhdl:33:17:@195ns:(report note): data_read = 0
prueba.vhdl:33:17:@205ns:(report note): data_read = 1
prueba.vhdl:33:17:@215ns:(report note): data_read = 1
prueba.vhdl:33:17:@225ns:(report note): data_read = 1
prueba.vhdl:33:17:@235ns:(report note): data_read = 1
prueba.vhdl:33:17:@245ns:(report note): data_read = 1
我们发现 prueba.txt 中的所有整数都被读取了。
注意我添加了一个名为 len
的变量来保存 L
中可用的字符数。每个 read
或每个 readline
len
都会更新。如果行中没有更多字符,我们就不会尝试读取。
CLOCK
过程中对Now
的求值和reading
过程中额外的wait until rising_edge(clk);
及后面的wait
只是为了停止模拟波形在哪里有用。
我们使用
L'length
来告诉我们一行中是否还有更多数据,或者我们是否应该掉到外部 while loop
中,如果不在文件末尾则调用 readline
。
您还可以注意到仅使用 'length
属性即可重写该过程:
reading:
process
constant filename: string := "prueba.txt";
file f: text open read_mode is filename;
variable L: line;
variable data_read: integer;
variable char: character;
begin
while not endfile(f) loop
readline(f, L);
while L'length > 0 loop
read (L, data_read);
if L'length > 0 then
read (L, char);
end if;
wait until rising_edge(clk);
d_out <= data_read;
report "data_read = " & integer'image(data_read);
end loop;
end loop;
wait until rising_edge(clk);
wait;
end process;
这给出了相同的答案。如果我们要做一些聪明的事情,比如扔掉评论,我们会使用 len
变量,这也需要我们扫描 L
和 trim 尾随白色 space。我们可以为 len
赋值,但不能为 L'length
赋值。因为在您的 prueba.txt 中没有尾随最后一个数据的内容,所以我们可以简单地使用 length
属性。
您可以研究这个包,它包含最多 3 个维度的动态大小数组类型,可以 load/save from/to csv 和原始文件。
https://github.com/LarsAsplund/vunit/blob/master/vhdl/array/src/array_pkg.vhd
它是 VUnit VHDL 测试框架的一部分。