我正在尝试从文件中读取矩阵,其中包含灰度图像像素的颜色。之后,我将必须将读取的数据放入寄存器并对其执行一些操作。当我尝试模拟我的代码时,可以在“数据”信号中正确读取数据,但是当我尝试存储元素时,我可以在“ 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;
答案 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
我们看到了:
在哪里似乎正确读取了矩阵值。 last_elem
和test
一样具有默认值(INTEGER'LOW,-2147483648),两个声明都没有初始值。
过程敏感性列表中的Data
和test
都不会在计划分配的同一模拟周期中发生。每个进程至少执行一次。
过程敏感性列表也存在问题。该过程将针对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_status
和endfile
测试有效。
对测试平台进行了其他更改:
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
时。
正如Tricky在评论中指出的,test
被分配了Data(0, 0)
的值,该值随后被分配给last_element
并且实际上包含矩阵的第一个元素。