VHDL textio,从文件中读取图像

问题描述 投票:0回答:3

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

我的代码出了什么问题?

image file vhdl fpga
3个回答
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 :(报告说明):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过程中的CLOCKwait until rising_edge(clk);过程中额外的wait以及reading的评估只是为了停止波形有用的模拟。


We use 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属性。


0
投票

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

L.all

因此,要获得角色,您可以:

L.all(1) = ','

作为简写,您还可以:

L(1) = ','

0
投票

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.