如何用clk在vhdl中逐行读取文本文件



我正在尝试在时钟事件中逐行读取文本文件以输出。但我的代码只是读取每个时钟中的第一个元素!问题出在哪里?

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上重新打开和关闭文件。

只有waituntil(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;

最新更新