简体   繁体   English

将未知大小的文件行读取为VHDL中的字符串

[英]Read file line of unknown size as string in VHDL

What I have 我有的

I'm trying to make a Test Bench where a file of one single line, where posible characters are "1" and "0". 我正在尝试建立一个测试平台,其中包含一行的文件,可能的字符为“ 1”和“ 0”。 I've to read them all, and use one by one as input in my DUT. 我必须全部阅读它们,并在我的DUT中一一使用。

So, in my TB, I've defined a process like the following, in order to read the file an pass it values to my 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;

What I think it's happening 我认为这正在发生

I'm reading the first (and only) line of my file with the first readline execution. 我正在执行第一次readline读取文件的第一行(也是唯一行)。 After this, this loop shouldn't execute again. 此后,此循环不应再执行。

Then, data from file should be inside rdline . 然后,来自file的数据应位于rdline So I've to process it. 所以我必须处理它。 In order to do it, I've tried to loop over rdline length, but this loop doesn't execute. 为了做到这一点,我试图在rdline长度上循环,但是此循环没有执行。

for j in 1 to rdline'length-1 loop

So I thought I need to read this line in order to loop over it, and tried to move its data to a string var. 因此,我认为我需要阅读此行才能对其进行循环,然后尝试将其数据移至string var。 The problem is that vector var like string need to have a defined size, and I don't know the file line size . 问题是像字符串这样的向量var需要具有定义的大小,而我不知道文件行大小

What have I tried 我尝试了什么

I've tried different ways to accomplish it, like reading each time 4 chars from rdline into a string, process it, then repeat. 我尝试了不同的方法来完成它,例如每次将4个字符从rdline到一个字符串中,进行处理,然后重复。 However, I couldn't make it work. 但是,我无法使其工作。

I've found quite lot examples on Google about reading files with VHDL, but they're all pretty the same, and all have defined line formats, like columns or expected integers, where I just have an unknown text of one line. 我在Google上发现了很多有关使用VHDL读取文件的示例,但是它们都是一样的,并且都定义了行格式,例如列或期望的整数,其中我只有一行的未知文本。

I guess it could be achieved by reading from rdline var in some way, but I can't achieve it. 我想可以通过以某种方式从rdline var读取来实现,但是我无法实现。 Could you help me to code it? 您能帮我编码吗?

Thank you in advance 先感谢您

Your example isn't an MCVE . 您的示例不是MCVE

This readed_char := line_content(j); readed_char := line_content(j); doesn't work when line_content isn't loaded. 未加载line_content时不起作用。 Otherwise your attempt to read values is basically sound. 否则,您尝试读取值的尝试基本上是合理的。

The end of line is not contained in a read LINE buffer, there's no reason to not read the last character of rdline. 行的结尾不包含在读取的LINE缓冲区中,没有理由不读取rdline的最后一个字符。 An end of line is signaled by one or more format effectors other than horizontal tab, and just the line contents are present. 除了水平制表符外,行尾由一个或多个格式执行器发出信号,仅存在行内容。

There's also this inference that you have some relationship to a clock edge and not just a clock period. 还有一个推断,您与时钟沿有一定关系,而不仅仅是时钟周期。 The following example shows that. 以下示例说明了这一点。 Note you can also supply an offset from an edge using a wait for time_value . 请注意,您还可以使用wait for time_value提供距边缘的偏移量。

A loop constant is declared in the loop statement. 在循环语句中声明了循环常数。 The variable j you declared is not the same j the loop uses. 您声明的变量j与循环使用的j不同。 The loop statement hides the j in the outer declarative region (the variable declaration in the process statement). 循环语句将j隐藏在外部声明性区域(process语句中的变量声明)中。

Your code treats any other character in the string buffer than '1' as a '0'. 您的代码会将字符串缓冲区中除“ 1”以外的任何其他字符都视为“ 0”。 I didn't change that, do demonstrate it. 我没有改变,请演示一下。 You should be aware of the impact. 您应该意识到其影响。

A LINE is an allocated string of some length dependent on the length of a line in your read file. LINE是分配的字符串,其长度取决于读取文件中一行的长度。 Every time you call readline the string rdline points to is updated. 每次您调用readline时,rdline指向的字符串都会更新。 It doesn't leak memory, the previous buffer rdline pointed to released. 它不会泄漏内存,先前的缓冲区rdline指向释放。 You can read the length by using the 'RIGHT attribute or as in this case simply consume all the characters. 您可以使用'RIGHT属性来读取长度,或者在这种情况下只需消耗所有字符即可。

There may be line length limits in a VHDL tool implementation. VHDL工具实现中可能存在行长限制。 There are none defined in the standard other than the maximum length of a string (POSITIVE'RIGHT). 除了字符串的最大长度(POSITIVE'RIGHT)外,标准中没有其他定义。

An MCVE: 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;

And for DatosEntrada.dat containing: 对于DatosEntrada.dat,其中包含:

11011110001HELLO11230000 11011110001HELLO11230000

That produces: 产生:

foo.png

Where you can see all non '1' characters are interpreted as '0'. 您可以在其中看到的所有非“ 1”字符都被解释为“ 0”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM