我正在尝试制作一个测试台,其中包含一行文件,其中有效字符为“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需要有一个已定义的大小,而我不知道文件行大小。
我已经尝试了不同的方法来实现它,比如每次将4个字符从rdline
读入字符串,处理它,然后重复。但是,我无法使其发挥作用。
我在Google上发现了很多关于使用VHDL读取文件的例子,但它们都非常相似,并且都定义了行格式,例如列或预期的整数,其中我只有一行的未知文本
我想这可以通过以某种方式从rdline
var读取来实现,但我无法实现它。你能帮我编码吗?
提前谢谢
答案 0 :(得分:3)
您的示例不是MCVE。
当没有加载line_content时,此readed_char := line_content(j);
无法正常工作。否则,您尝试读取值基本上是合理的。
行结束不包含在读取LINE缓冲区中,没有理由不读取rdline的最后一个字符。行末由一个或多个格式效应器发出信号,而不是水平制表符,只有行内容存在。
此推论还表明,您与时钟边缘有一些关系,而不仅仅是时钟周期。以下示例显示了这一点。请注意,您还可以使用wait for time_value
从边缘提供偏移量。
循环常量在循环语句中声明。您声明的变量j
与循环使用的j
不同。循环语句隐藏外部声明区域中的j
(进程语句中的变量声明)。
您的代码会将字符串缓冲区中的任何其他字符视为&#39; 1&#39;作为&#39; 0&#39;。我没有改变它,做了证明。你应该知道这种影响。
LINE是一段长度,取决于读取文件中一行的长度。每次调用readline时,字符串rdline指向的都会更新。它没有泄漏内存,前面的缓冲区rdline指向释放。您可以使用&#39; RIGHT属性读取长度,或者在这种情况下只使用所有字符。
VHDL工具实现中可能存在行长度限制。除了字符串的最大长度(POSITIVE&#39; RIGHT)之外,标准中没有定义。
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
产生:
你可以看到所有非&#39; 1&#39;字符被解释为&#39; 0&#39;。