我正在尝试学习如何在FPGA中实现图像处理算法,并且我正在使用包含bmp图像的txt文件(使用MATLAB转换)。
我在使用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;
我的代码出了什么问题?
我不明白为什么代码没有读取所有行,当它结束时跳转到下一行。
你只想在下一个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 :(报告说明):data_read = 1 prueba.vhdl:33:17:@ 15ns :(报告说明):data_read = 1 prueba.vhdl:33:17:@ 25ns :(报告说明):data_read = 0 prueba.vhdl:33:17:@ 35ns :(报告说明):data_read = 0 prueba.vhdl:33:17:@ 45ns :(报告说明):data_read = 0 prueba.vhdl:33:17:@ 55ns :(报告说明):data_read = 0 prueba.vhdl:33:17:@ 65ns :(报告说明):data_read = 1 prueba.vhdl:33:17:@ 75ns :(报告说明):data_read = 1 prueba.vhdl:33:17:@ 85ns :(报告说明):data_read = 1 prueba.vhdl:33:17:@ 95ns :(报告说明):data_read = 1 prueba.vhdl:33:17:@ 105ns :(报告说明):data_read = 1 prueba.vhdl:33:17:@ 115ns :(报告说明):data_read = 0 prueba.vhdl:33:17:@ 125ns :(报告说明):data_read = 0 prueba.vhdl:33:17:@ 135ns :(报告说明):data_read = 0 prueba.vhdl:33:17:@ 145ns :(报告说明):data_read = 0 prueba.vhdl:33:17:@ 155ns :(报告说明):data_read = 0 prueba.vhdl:33:17:@ 165ns :(报告说明):data_read = 0 prueba.vhdl:33:17:@ 175ns :(报告说明):data_read = 1 prueba.vhdl:33:17:@ 185ns :(报告说明):data_read = 1 prueba.vhdl:33:17:@ 195ns :(报告说明):data_read = 0 prueba.vhdl:33:17:@ 205ns :(报告说明):data_read = 1 prueba.vhdl:33:17:@ 215ns :(报告说明):data_read = 1 prueba.vhdl:33:17:@ 225ns :(报告说明):data_read = 1 prueba.vhdl:33:17:@ 235ns :(报告说明):data_read = 1 prueba.vhdl:33:17:@ 245ns :(报告说明):data_read = 1
我们在哪里找到prueba.txt中的所有整数都被读取。
注意我添加了一个名为len
的变量来保存L
中可用的字符数。每个read
或每个readline
len
都会更新。如果线上没有其他字符,我们不会尝试阅读。
Now
过程中的CLOCK
和wait until rising_edge(clk);
过程中额外的wait
以及reading
的评估只是为了停止波形有用的模拟。
L'length
to tell us if there are any more datums on a line or whether we should fall out into the outer while loop
and call readline
if not at the end of the file.
您还可以注意到只能使用'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
和修剪尾随空格。我们可以为len
而不是L'length
赋值。因为prueba.txt中的最后一个数据没有任何结尾,所以我们可以简单地使用length
属性。
L是指向字符串的指针。要取消引用指针,您需要:
L.all
因此,要获得角色,您可以:
L.all(1) = ','
作为简写,您还可以:
L(1) = ','
您可以研究此包,其中包含最多3维的动态大小的数组类型,可以从/向csv和原始文件加载/保存。
https://github.com/LarsAsplund/vunit/blob/master/vhdl/array/src/array_pkg.vhd
它是VUnit VHDL测试框架的一部分。