在 VHDL 中将未知大小的文件行读取为字符串
Read file line of unknown size as string in VHDL
我正在尝试制作一个测试台,其中包含一行文件,其中可能的字符为“1”和“0”。我必须全部阅读它们,并在我的 DUT 中将它们作为输入使用。
因此,在我的 TB 中,我定义了一个如下所示的过程,以便读取文件并将其值传递给我的 DUT。
stim_proc: process
file input_file: TEXT is in "DatosEntrada.dat";
variable rdline : LINE;
variable line_content : string ( 1 to 4);
variable readed_char : character;
variable j : integer := 0;
begin
while not endfile(input_file) loop
readline(input_file, rdline);
--read(rdline, line_content);
for j in 1 to rdline'length-1 loop
readed_char := line_content(j);
if (readed_char = '1') then
input <= '1';
else
input <= '0';
end if;
wait for clk_period;
end loop;
end loop;
end process;
我在第一次 readline
执行时读取文件的第一行(也是唯一一行)。在此之后,此循环不应再次执行。
那么,文件中的数据应该在rdline
里面。所以我必须处理它。为了做到这一点,我试图循环 rdline
长度,但这个循环没有执行。
for j in 1 to rdline'length-1 loop
所以我认为我需要阅读这一行以便遍历它,并尝试将其数据移动到 string
var。问题是 vector var like string 需要有一个定义的大小,我不知道文件行大小。
我尝试每次将 rdline
中的 4 个字符读入一个字符串,处理它,然后重复。但是,我无法让它工作。
我发现了很多关于读取定义了行格式的文件的示例,例如列或预期的整数。
但是我怎样才能读到一行未知的文字呢?
当 line_content
未加载时,此 readed_char := line_content(j);
不起作用。否则你读取值的尝试基本上是正确的。
行尾不包含在读取行缓冲区中,没有理由不读取 rdline 的最后一个字符。行尾由一个或多个除水平制表符之外的格式效应器发出信号,并且仅存在行内容。
还有这样的推论,你与时钟边沿有某种关系,而不仅仅是时钟周期。下面的例子说明了这一点。请注意,您还可以使用 wait for time_value
.
提供与边缘的偏移量
循环语句中声明了一个循环常量。您声明的变量 j
与循环使用的 j
不同。循环语句隐藏了外层声明区域的j
(过程语句中的变量声明)
您的代码将字符串缓冲区中除“1”以外的任何其他字符都视为“0”。我没有改变它,请证明它。您应该了解影响。
LINE 是分配的字符串,其长度取决于读取文件中一行的长度。每次调用 readline 时,rdline 指向的字符串都会更新。它不会泄漏内存,之前的缓冲区 rdline 指向已释放。您可以使用 'RIGHT 属性读取长度,或者在本例中简单地使用所有字符。
VHDL 工具实现中可能存在行长度限制。除了字符串的最大长度 (POSITIVE'RIGHT) 之外,标准中还定义了 none。
一个 MCVE:
library ieee;
use ieee.std_logic_1164.all;
use std.textio.all;
entity foo is
end entity;
architecture fum of foo is
signal input: std_logic ;
signal clk: std_logic := '0';
constant clk_period: time := 10 ns;
begin
stim_proc:
process
file input_file: TEXT is in "DatosEntrada.dat";
variable rdline: LINE;
-- variable line_content : string ( 1 to 4);
-- variable readed_char : character;
-- variable j: integer := 0;
begin
while not endfile(input_file) loop
readline(input_file, rdline);
--read(rdline, line_content);
-- for j in 1 to rdline'length - 1 loop -- EOL not in rdline
for j in rdline'range loop
-- readed_char := line_content(j);
-- if readed_char = '1' then
if rdline(j) = '1' then -- changed
input <= '1';
else
input <= '0';
end if;
-- wait for clk_period; -- sync to edge instead
wait until falling_edge(clk); -- input related to clk edge
end loop;
end loop;
wait; -- added prevents needless loops
end process;
CLOCK:
process
begin
wait for clk_period/2;
clk <= not clk;
if now > 32 * clk_period then
wait;
end if;
end process;
end architecture;
并且 DatosEntrada.dat 包含:
11011110001HELLO11230000
产生:
您可以看到所有非“1”字符都被解释为“0”。
我正在尝试制作一个测试台,其中包含一行文件,其中可能的字符为“1”和“0”。我必须全部阅读它们,并在我的 DUT 中将它们作为输入使用。
因此,在我的 TB 中,我定义了一个如下所示的过程,以便读取文件并将其值传递给我的 DUT。
stim_proc: process
file input_file: TEXT is in "DatosEntrada.dat";
variable rdline : LINE;
variable line_content : string ( 1 to 4);
variable readed_char : character;
variable j : integer := 0;
begin
while not endfile(input_file) loop
readline(input_file, rdline);
--read(rdline, line_content);
for j in 1 to rdline'length-1 loop
readed_char := line_content(j);
if (readed_char = '1') then
input <= '1';
else
input <= '0';
end if;
wait for clk_period;
end loop;
end loop;
end process;
我在第一次 readline
执行时读取文件的第一行(也是唯一一行)。在此之后,此循环不应再次执行。
那么,文件中的数据应该在rdline
里面。所以我必须处理它。为了做到这一点,我试图循环 rdline
长度,但这个循环没有执行。
for j in 1 to rdline'length-1 loop
所以我认为我需要阅读这一行以便遍历它,并尝试将其数据移动到 string
var。问题是 vector var like string 需要有一个定义的大小,我不知道文件行大小。
我尝试每次将 rdline
中的 4 个字符读入一个字符串,处理它,然后重复。但是,我无法让它工作。
我发现了很多关于读取定义了行格式的文件的示例,例如列或预期的整数。
但是我怎样才能读到一行未知的文字呢?
当 line_content
未加载时,此 readed_char := line_content(j);
不起作用。否则你读取值的尝试基本上是正确的。
行尾不包含在读取行缓冲区中,没有理由不读取 rdline 的最后一个字符。行尾由一个或多个除水平制表符之外的格式效应器发出信号,并且仅存在行内容。
还有这样的推论,你与时钟边沿有某种关系,而不仅仅是时钟周期。下面的例子说明了这一点。请注意,您还可以使用 wait for time_value
.
循环语句中声明了一个循环常量。您声明的变量 j
与循环使用的 j
不同。循环语句隐藏了外层声明区域的j
(过程语句中的变量声明)
您的代码将字符串缓冲区中除“1”以外的任何其他字符都视为“0”。我没有改变它,请证明它。您应该了解影响。
LINE 是分配的字符串,其长度取决于读取文件中一行的长度。每次调用 readline 时,rdline 指向的字符串都会更新。它不会泄漏内存,之前的缓冲区 rdline 指向已释放。您可以使用 'RIGHT 属性读取长度,或者在本例中简单地使用所有字符。
VHDL 工具实现中可能存在行长度限制。除了字符串的最大长度 (POSITIVE'RIGHT) 之外,标准中还定义了 none。
一个 MCVE:
library ieee;
use ieee.std_logic_1164.all;
use std.textio.all;
entity foo is
end entity;
architecture fum of foo is
signal input: std_logic ;
signal clk: std_logic := '0';
constant clk_period: time := 10 ns;
begin
stim_proc:
process
file input_file: TEXT is in "DatosEntrada.dat";
variable rdline: LINE;
-- variable line_content : string ( 1 to 4);
-- variable readed_char : character;
-- variable j: integer := 0;
begin
while not endfile(input_file) loop
readline(input_file, rdline);
--read(rdline, line_content);
-- for j in 1 to rdline'length - 1 loop -- EOL not in rdline
for j in rdline'range loop
-- readed_char := line_content(j);
-- if readed_char = '1' then
if rdline(j) = '1' then -- changed
input <= '1';
else
input <= '0';
end if;
-- wait for clk_period; -- sync to edge instead
wait until falling_edge(clk); -- input related to clk edge
end loop;
end loop;
wait; -- added prevents needless loops
end process;
CLOCK:
process
begin
wait for clk_period/2;
clk <= not clk;
if now > 32 * clk_period then
wait;
end if;
end process;
end architecture;
并且 DatosEntrada.dat 包含:
11011110001HELLO11230000
产生:
您可以看到所有非“1”字符都被解释为“0”。