Чтение матрицы из файла - PullRequest
0 голосов
/ 21 апреля 2019

Я пытаюсь прочитать матрицу из файла, он содержит цвета пикселей серого изображения. После этого мне придется поместить данные, которые я прочитал, в регистр и выполнить некоторые операции с ним. Когда я пытаюсь смоделировать мой код, данные считываются правильно в сигнале «данные», но когда я пытаюсь сохранить элемент, я читаю в сигнале «тест», чтобы показать его в выводе «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 Ответ

1 голос
/ 22 апреля 2019

Предоставление Минимального, Полного и Проверяемого примера для вашего кода:

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_elem имеет значение по умолчанию (INTEGER'LOW, -2147483648), как и test, оба объявления не имеют начального значения.

Ни Data, ни test отсутствуют в списке чувствительности процесса.назначения не будут выполняться в том же цикле моделирования, для которого запланировано назначение.Каждый процесс выполняется как минимум один раз.

Существует также проблема со списком чувствительности процесса.Процесс будет выполняться для каждого события clk, периодически открывая файл, читая данные и закрывая файл.

Правильным решением этих двух проблем будет удаление списка чувствительности процесса и добавление окончательного варианта.оператор ожидания (wait;) после file_close.Также добавьте оператор ожидания с нулевым инкрементным временем моделирования (например, wait for 0 ns;) перед каждым назначением сигнала в зависимости от значения предыдущего назначения сигнала в процессе.

Существует также проблема обнаружения ошибок во время операций TEXTIO (file_open, read_line).Вы приложили все усилия, чтобы закрыть файл.Как насчет проверки успешного открытия файла и ENDFILE перед выполнением процедуры read_line?


    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 будет обновлено после последовательных циклов дельта-моделирования,

Оператор ожидания заставляет исполняющийся процесс приостанавливаться до тех пор, пока не будет выполнено условие.Оператор ожидания без условия предполагает предложение времени ожидания TIME'HIGH.

Оператор ожидания с условием тайм-аута (здесь 0 ns для первых двух) приостановит процесс, пока не будет выполнено условие.Инкрементальная задержка эквивалентна текущему времени моделирования плюс выражение времени.

Поскольку на текущее время моделирования запланировано еще одно событие, произойдет цикл дельта-моделирования, в котором процесс возобновится.В начале каждого цикла моделирования прогнозируемые значения выходной формы волны, запланированные на текущее время моделирования, вызывают обновления сигнала, где можно оценить эффективное значение сигнала (как в операторе назначения).Это произойдет для обоих из первых двух операторов ожидания.

При выполнении последнего оператора ожидания без предложения timeout предполагается, что в предложении timeout указано TIME'HIGH, процесс не возобновится во время моделирования.

Вы можете доказать, что тесты open_status и endfile работают, управляя файловой системой хоста (путь и разрешения) и содержимым файла image.txt.

С дополнительным изменением в испытательном стенде:

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.

Как указывает Трики в комментарии, test присваивается значение Data(0, 0), которое затем присваивается last_element и фактически содержит первый элемент матрицы.

...