Предоставление Минимального, Полного и Проверяемого примера для вашего кода:
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
Мы видим:
Где значения матрицы отображаются для правильного считывания.Сигнал 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;
Вы можете продемонстрировать, что код выглядит функционально посредством моделирования:
При моделировании вы только начнете процесс с первой строки один раз, только возобновите ожидание обновления сигнала только дважды и получите только одно сообщение от
report "read_file opened for read" severity NOTE;
при оценке open_status
.
Как указывает Трики в комментарии, test
присваивается значение Data(0, 0)
, которое затем присваивается last_element
и фактически содержит первый элемент матрицы.