【问题标题】:Read file line of unknown size as string in VHDL将未知大小的文件行读取为 VHDL 中的字符串
【发布时间】:2016-02-04 17:46:53
【问题描述】:

我正在尝试制作一个测试台,其中包含单行文件,其中可能的字符是“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 个字符读入一个字符串,处理它,然后重复。但是,我无法让它工作。

我发现了很多关于读取已定义行格式(如列或预期整数)的文件的示例。

但是我如何才能阅读一行未知的文本呢?

【问题讨论】:

  • 如果你只想要一个 Readline 调用(读取一行),只需删除外部循环。然后我建议报告 rdline'length 和实际文本是什么,看看发生了什么。

标签: testing vhdl test-bench


【解决方案1】:

当line_content 未加载时,此readed_char := line_content(j); 不起作用。否则,您读取值的尝试基本上是正确的。

行尾不包含在读取的 LINE 缓冲区中,没有理由不读取 rdline 的最后一个字符。行尾由一个或多个除水平制表符之外的格式效应器发出信号,并且仅存在行内容。

还有这样的推论,即您与时钟边沿有某种关系,而不仅仅是时钟周期。下面的例子说明了这一点。请注意,您还可以使用 wait for time_value 提供与边缘的偏移量。

在循环语句中声明了一个循环常量。您声明的变量j 与循环使用的j 不同。循环语句将j隐藏在外部声明区域(进程语句中的变量声明)。

您的代码将字符串缓冲区中除“1”以外的任何其他字符视为“0”。我没有改变它,做演示它。您应该意识到影响。

LINE 是一个分配的字符串,其长度取决于读取文件中行的长度。每次调用 readline 时,都会更新 rdline 指向的字符串。它不会泄漏内存,先前的缓冲区 rdline 指向已释放。您可以通过使用 'RIGHT 属性来读取长度,或者在这种情况下只需消耗所有字符。

VHDL 工具实现中可能存在行长度限制。除了字符串的最大长度(POSITIVE'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

产生:

您可以看到所有非“1”字符都被解释为“0”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-11
    • 1970-01-01
    • 1970-01-01
    • 2020-05-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多