VHDL textio,从文件中读取图像

时间:2015-06-27 15:35:07

标签: image file vhdl fpga

我正在尝试学习如何在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;

我的代码出了什么问题?

3 个答案:

答案 0 :(得分:1)

我不明白为什么代码没有读取所有行,结束时跳转到下一行。

您只是在下一个readline之前尝试读取一个整数,然后读取一个逗号。

另请注意,只要您可以依靠一行中分隔连续整数的字符,您就不必关心该字符是什么(并且您不必看comma)。< / p>

要读取某一行上的每个整数,您需要注意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);流程中的额外waitreading的评估只是为了停止模拟波形很有用。

<小时/> 我们使用L'length告诉我们一行上是否还有更多基准,或者我们是否应该落入外部while loop并调用readline(如果不是在文件的末尾)。< p>

您还可以注意,只能使用'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属性。

答案 1 :(得分:0)

L是指向字符串的指针。要取消引用指针,您需要:

L.all

因此,要获得一个角色,你可以这样做:

L.all(1) = ','

作为速记,你也可以这样做:

L(1) = ','

答案 2 :(得分:0)

您可以研究此包,其中包含最多3维的动态大小数组类型,可以从/向csv和原始文件加载/保存。

https://github.com/LarsAsplund/vunit/blob/master/vhdl/array/src/array_pkg.vhd

它是VUnit VHDL测试框架的一部分。