我正在尝试在时钟事件中逐行读取文本文件以输出。但我的代码只是读取每个时钟中的第一个元素!问题出在哪里?
entity filter_tb is
PORT( clk : IN std_logic;
filter_out : OUT real
);
end filter_tb;
architecture filter_tb of filter_tb is
begin
process(clk)
file file_pointer : text;
variable line_content : real;
variable line_num : line;
begin
file_open(file_pointer,"myFile.txt",READ_MODE);
readline(file_pointer, line_num);
read(line_num, line_content);
filter_out <= line_content;
file_close(file_pointer);
end process;
end filter_tb;
myFile.txt:
0.0000000e+00
5.8778525e-01
9.5105652e-01
9.5105652e-01
5.8778525e-01
1.2246468e-16
根声明性区域中缺少一些上下文子句元素,以及使用设计模型的方法:
library ieee;
use ieee.std_logic_1164.all;
use std.textio.all;
entity filter_tb is
您只需要打开和关闭该文件一次。这分为几个阶段:打开文件,每个时钟读取一次数据,当没有更多数据时关闭文件并暂停过程,直到模拟结束。
architecture filter_tb of filter_tb is
begin
process -- (clk) -- process now contains wait statement
constant filename: string := "myFile.txt"; -- use more than once
file file_pointer: text;
variable line_content: real;
variable line_num: line;
variable filestatus: file_open_status;
begin
file_open (filestatus, file_pointer, filename, READ_MODE);
report filename & LF & HT & "file_open_status = " &
file_open_status'image(filestatus);
assert filestatus = OPEN_OK
report "file_open_status /= file_ok"
severity FAILURE; -- end simulation
while not ENDFILE (file_pointer) loop
wait until falling_edge(clk); -- once per clock
readline (file_pointer, line_num);
read (line_num, line_content);
filter_out <= line_content;
end loop;
wait until falling_edge(clk); -- the last datum can be used first
file_close (file_pointer);
report filename & " closed.";
wait;
end process;
end architecture filter_tb;
这使用了一个不同的file_open
过程调用,该调用还会在报告时分配一个file_open_status
变量,这会使您明显地重复打开文件。
在没有更多的行要读取之后,文件将被关闭。注意循环语句中等待时钟边缘事件的等待语句,该语句将在每个时钟读取一个数据。
最后的wait语句将在模拟的剩余部分挂起进程。
使用顶级端口,我们可以添加一个封闭的测试台:
library ieee;
use ieee.std_logic_1164.all;
entity tb_filter_tb is
end entity;
architecture foo of tb_filter_tb is
signal clk: std_logic := '0';
signal filter_out: real;
begin
DUT:
entity work.filter_tb
port map (
clk => clk,
filter_out => filter_out
);
CLOCK:
process
begin
wait for 5 ns;
clk <= not clk;
if now > 90 ns then
wait;
end if;
end process;
MONITOR:
process
begin
wait until falling_edge(clk);
wait for 0 ns;
report "filter_out = " & real'image(filter_out);
end process;
end architecture;
监控进程可以报告每个活动时钟边缘的filter_out值:
ghdl -r tb_filter_tb filter_tb.vhdl:25:13:@0ms:(report note): myFile.txt file_open_status = open_ok filter_tb.vhdl:80:9:@10ns:(report note): filter_out = 0.0 filter_tb.vhdl:80:9:@20ns:(report note): filter_out = 5.8778525e-1 filter_tb.vhdl:80:9:@30ns:(report note): filter_out = 9.5105652e-1 filter_tb.vhdl:80:9:@40ns:(report note): filter_out = 9.5105652e-1 filter_tb.vhdl:80:9:@50ns:(report note): filter_out = 5.8778525e-1 filter_tb.vhdl:80:9:@60ns:(report note): filter_out = 1.2246468e-16 filter_tb.vhdl:42:9:@70ns:(report note): myFile.txt closed. filter_tb.vhdl:80:9:@70ns:(report note): filter_out = 1.2246468e-16 filter_tb.vhdl:80:9:@80ns:(report note): filter_out = 1.2246468e-16 filter_tb.vhdl:80:9:@90ns:(report note): filter_out = 1.2246468e-16
直到模拟结束。
您将在每个clk
上重新打开和关闭文件。
只有wait
until
和(clk)
的rising_edge
在过程中发生。保持文件打开
entity filter_tb is
PORT( clk : IN std_logic;
filter_out : OUT real
);
end filter_tb;
architecture filter_tb of filter_tb is
begin
process
file file_pointer : text;
variable line_content : real;
variable line_num : line;
begin
file_open(file_pointer,"myFile.txt",READ_MODE);
while not endfile(file_pointer) loop
readline(file_pointer, line_num);
read(line_num, line_content);
filter_out <= line_content;
wait until rising_edge(clk);
end loop;
file_close(file_pointer);
wait;
end process;
end filter_tb;