从文件读取矩阵

时间:2019-04-21 15:51:04

标签: vhdl

我正在尝试从文件中读取矩阵,其中包含灰度图像像素的颜色。之后,我将必须将读取的数据放入寄存器并对其执行一些操作。当我尝试模拟我的代码时,可以在“数据”信号中正确读取数据,但是当我尝试存储元素时,我可以在“ test”信号中读取以在“ last_elem”输出中显示它,该命令显示- 2147483648。我在做什么错,为什么我不能访问读取的数据?

entity Main is
Port(
rstb:in std_logic;
clk:in std_logic;
row:out integer;
col:out integer;
last_elem:out integer
);
end Main;

architecture Behavioral of Main is
type matrixData is array(0 to 240, 0 to 217) of integer;
signal data:matrixData;
signal test:integer;

begin
    process(clk)
    file read_file:text;
    VARIABLE file_line:LINE;
    VARIABLE row_counter:INTEGER:=0;
    variable rows:integer;
    variable cols:integer;
    variable read_value:integer;
    begin


    file_open(read_file, "D:\Faculta\An 3 Sem 2\SCS\image.txt", read_mode);
    readline(read_file,file_line);
    read(file_line, rows);
    read(file_line, cols);
    row<=rows;
    col<=cols;

    for i in 0 to rows-1 loop
        readline(read_file,file_line);
        for j in 0 to cols-1 loop
                read(file_line, read_value);
                data(i,j)<=read_value;
        end loop;
    end loop;



    test<=data(0,0);
    last_elem<=test;

    file_close(read_file);
    end process;

end Behavioral;

1 个答案:

答案 0 :(得分:1)

为您的代码提供Minimal, Complete, and Verifiable example

library ieee;
use ieee.std_logic_1164.all;
use std.textio.all;

entity main is
    port (
        rstb:       in  std_logic;
        clk:        in  std_logic;
        row:        out integer;
        col:        out integer;
        last_elem:  out integer
    );
end entity main;

architecture behavioral of main is
    -- type matrixdata is array (0 to 240, 0 to 217) of integer;
    type matrixdata is array (0 to 3, 0 to 2) of integer;
    signal data:    matrixdata;
    signal test:    integer;

begin
    process (clk)
        file read_file:         text;
        variable file_line:     line;
        variable row_counter:   integer := 0;
        variable rows:          integer;
        variable cols:          integer;
        variable read_value:    integer;
    begin
        --file_open(read_file, "d:\faculta\an 3 sem 2\scs\image.txt", read_mode);
        file_open (read_file, "image.txt", read_mode);
        readline (read_file, file_line);
        read (file_line, rows);
        read (file_line, cols);
        row <= rows;
        col <= cols;

        for i in 0 to rows - 1 loop
            readline (read_file, file_line);
            for j in 0 to cols - 1 loop
                    read(file_line, read_value);
                    data(i,j) <= read_value;
            end loop;
        end loop;

        test <= data(0, 0);
        last_elem <= test;

        file_close(read_file);
    end process;
end behavioral;

library ieee;
use ieee.std_logic_1164.all;

entity main_tb is
end entity;

architecture foo of main_tb is
    component main is
        port (
            rstb:       in  std_logic;
            clk:        in  std_logic;
            row:        out integer;
            col:        out integer;
            last_elem:  out integer
        );
    end component main;
    signal rstb:       std_logic := '1';
    signal clk:        std_logic := '0';
    signal row:        integer;
    signal col:        integer;
    signal last_elem:  integer;
begin
DUT:
    main
        port map (
            rstb => rstb,
            clk => clk,
            row => row,
            col => col,
            last_elem => last_elem
        );
WAVEFORM_DISPLAY_STIMULUS:
    process
    begin
        wait for 0 ns;
        wait for 1 ns;
        wait;
    end process;
end architecture;

针对较小的二维矩阵数据类型进行了修改,并提供了一个输入文件:

images.txt

4 3
0 0 0
1 1 1
2 2 2
3 3 3

我们看到了:

main_tb.jpg

在哪里似乎正确读取了矩阵值。 last_elemtest一样具有默认值(INTEGER'LOW,-2147483648),两个声明都没有初始值。

过程敏感性列表中的Datatest都不会在计划分配的同一模拟周期中发生。每个进程至少执行一次。

过程敏感性列表也存在问题。该过程将针对clk上的每个事件执行,重复打开文件,读取数据并关闭文件。

针对这两个问题的正确解决方法是删除进程敏感性列表,并在file_close之后添加最终的等待语句(wait;)。还要在每个信号分配之前添加一个零增量模拟时间(例如wait for 0 ns;)的等待语句,具体取决于过程中的先前信号分配值。

在TEXTIO操作(file_open,read_line)期间还存在错误检测的问题。您已经为关闭文件付出了很多麻烦。在执行过程read_line之前检查打开文件和ENDFILE是否成功?


    process
        file read_file:         text;
        variable file_line:     line;
        variable row_counter:   integer := 0;
        variable rows:          integer;
        variable cols:          integer;
        variable read_value:    integer;
        variable open_status:   FILE_OPEN_STATUS; -- ADDED
    begin
        --file_open(read_file, "d:\faculta\an 3 sem 2\scs\image.txt", read_mode);
        -- file_open (read_file, "image.txt", read_mode);
        file_open (open_status, read_file, "image.txt", read_mode);

        case open_status is  -- ADDED
             when OPEN_OK =>
                report "read_file opened for read" severity NOTE;
            when STATUS_ERROR =>
                report "read_file already open" severity FAILURE;
            when NAME_ERROR =>
                report "read_file file name not found" severity FAILURE;
            when MODE_ERROR =>
                report "read_file can't be opened for read" severity FAILURE;
        end case;

        if endfile(read_file) then  -- ADDED
            report "can't read first line from read_file"
            severity FAILURE;
        end if;
        readline (read_file, file_line);
        read (file_line, rows);
        read (file_line, cols);
        row <= rows;
        col <= cols;

        for i in 0 to rows - 1 loop
            if endfile(read_file) then   -- ADDED
                report "can't read line for all rows from read_file"
                severity FAILURE;
            end if;
            readline (read_file, file_line);
            for j in 0 to cols - 1 loop
                    read(file_line, read_value);
                    data(i,j) <= read_value;
            end loop;
        end loop;
        wait for 0 ns;  --  ADDED causes a delta cycle, data is updated
        test <= data(0, 0);
        wait for 0 ns;  -- ADDED causes a delta cycle, test is updated
        last_elem <= test;
        file_close(read_file);
        wait;           -- ADDED
    end process;

这将在初始化时一次加载数组 ,并且last_elem的值将在连续的增量模拟周期后更新。

wait语句使执行过程挂起,直到满足条件为止。没有条件的等待语句假定TIME'HIGH的超时子句。

带有超时子句的等待语句(此处为前两个0 ns)将暂停该过程,直到满足条件为止。增量延迟等于当前仿真时间加上时间表达式。

由于在当前模拟时间安排了另一个事件,因此将发生增量模拟周期,过程将继续进行。在每个模拟周期的开始,为当前模拟时间安排的预计输出波形值会导致信号更新,从而可以评估信号的有效值(如分配声明中所述)。对于前两个wait语句,都会发生这种情况。

在没有timeout子句的情况下命中最终的等待语句时,假设有TIME'HIGH的timeout子句,则该过程不会在模拟过程中再次恢复。

您可以通过操纵主机文件系统(路径和权限)和image.txt文件内容来证明open_statusendfile测试有效。

对测试平台进行了其他更改:

CLOCK:
    process
    begin
        wait for 5 ns;
        clk <= not clk;
        if now > 40 ns then
            wait;
        end if;
    end process;
-- WAVEFORM_DISPLAY_STIMULUS:
--     process
--     begin
--         wait for 0 ns;
--         wait for 1 ns;
--         wait;
--     end process;

您可以通过仿真演示代码是否起作用:

main_tb_fixed.jpg

在仿真时,您只会在第一行开始一次该过程,仅恢复两次以等待信号更新,并且仅收到一条消息

                report "read_file opened for read" severity NOTE; 

评估open_status时。

正如Tricky在评论中指出的,test被分配了Data(0, 0)的值,该值随后被分配给last_element并且实际上包含矩阵的第一个元素。