2015-06-27 87 views
0

我想学习如何在FPGA中实现图像处理算法,并执行此操作我正在处理包含bmp图像(使用MATLAB转换)的txt文件。VHDL textio,从文件中读取图像

我有使用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; 

什么是错我的代码?

+0

你有没有考虑过直接从软件驱动刺激模拟而不是通过文件?这个基于Python的示例处理位图,jpegs,tiff等,并自动比较输出的相似性:https://github.com/chiggs/oc_jpegencode – Chiggs

回答

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 :(报告说明):da ta_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 report):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:(报告注):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
(report report):data_read = 0
prueba.vhdl:33:17 (报告说明):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:(report note):data_read = 0
prueba.vhdl:33:17:@ 205ns:(report note):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或每个readlinelen。如果行中没有更多的字符,我们不会尝试阅读。

NowCLOCK过程评估和额外的wait until rising_edge(clk);并在reading过程以下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并修剪尾随空白。我们可以将值分配给len而不是L'length。由于在prueba.txt中最后一个数据没有结尾,所以我们可以简单地使用length属性。

+0

我试图运行此代码片段,它工作正常(如您所示),但我仍然不理解某些部分:为什么“len”必须在每个if和while部分中再次定义?我试图避免这一点,但后来它不起作用,我不知道为什么会发生这种情况。 – osuarez

0

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

L.all 

因此,要获得一个字符,你可以这样做:

L.all(1) = ',' 

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

L(1) = ','