【问题标题】:VHDL write to file does nothingVHDL写入文件什么都不做
【发布时间】:2016-05-13 07:32:55
【问题描述】:

我编写了一段 VHDL 代码的图像处理。为了测试,我用 Matlab 和一个相对简单的测试台创建了一个像素值文件(它只是将值从文件填充到输入)。我想将结果写入一个新文件,以便处理它们并查看生成的图像。

代码编译并运行测试台,我看到我输入的所有报告以检查它是否在任何地方停止,但包含结果的文件仍然是空的。 print 和 writeline 似乎都没有做任何事情。该文件存在并添加到 Vivado 中的项目中,因此我不必编写整个路径。模拟器输出中没有警告或错误。

我从herehere 获得了写入文件的代码,并将其扩展为每个时钟写入文件并在顶部添加标题。

color_out(0) 是一段输出。 color_out_v 输出有效。

有什么想法吗?我错过了什么?

Verify_data_process : process
variable my_line : line; 
file l_file      : TEXT;        -- open write_mode is "color_out.txt";   
begin -- process
file_open(l_file, "C:\Users\vevo\branches\Vivado_IP\repo\testing_data\color_out.txt", write_mode);
  wait until clk128_tb = '1';
    print(l_file, "R G B" );

    if(color_out_v = '1') then
    report "Color_out";
        write(my_line, integer'(to_integer(color_out(0).R)));
        write(my_line, integer'(to_integer(color_out(0).G)));
        write(my_line, integer'(to_integer(color_out(0).B)));
        writeline(l_file, my_line);
    report "write line";
    end if;
    file_close(l_file);
end process;

【问题讨论】:

  • 欢迎来到 SO。如果您提供了一些minimally reproduced your problem 的代码,将会有所帮助;相反,我不得不添加很多代码并取出很多代码,只是为了让您的代码编译和运行。完成that 后,我认为没有问题 - 它写入一个文件,其中包含我预期的内容。那么为什么要在我的文件中获取一些内容呢?我必须注释掉的一行是if(color_out_v = '1') then;显而易见的建议是color_out_v 永远不是1。如果你提供了 MCVE,我可以检查一下。
  • 顺便说一句:integer'(to_integer 中的限定是多余的:to_integer 返回一个integer;编译知道这一点,所以不需要限定。
  • @Matthew Taylor:我注意到了未来的评论。我一直觉得我应该尽可能少地编写代码以提高可读性。 color_out_v 变成 '1' 非常好,我相信如果没有,报告“写行”也不会发生。如果它适合你,我可能有一个我不知道的系统问题。
  • 为了可读性而加入尽可能少的代码是一件非常好的事情,但是与其把能够编译的东西拿出来,不如把没什么可编译的东西拿出来解决问题。这样,其他人可以轻松运行您的代码并轻松重现您的问题。还有另一个优势:将代码缩减到此 MCVE 的行为可能使您能够自己发现问题。无论如何,在这种情况下,我认为这将是一个好主意:您可以自己解决问题;如果没有,如何发布你最终得到的代码? ...
  • ...所以问题出在有一行代码,我将其注释掉以使其编译。

标签: vhdl vivado test-bench


【解决方案1】:

问题代码是每次clk128_tb有事件时打开和关闭文件,发现等于'1'。

Minimal, Complete, and Verifiable example 的核心是问题的流程:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use std.textio.all;

entity color_out is
end entity;

architecture foo of color_out is

    signal clk128_tb:   std_logic := '0';
    signal color_out_v: std_logic := '0';

    type pixel is record
        R: unsigned (7 downto 0);
        G: unsigned (7 downto 0);
        B: unsigned (7 downto 0);
    end record;
    type scan is array (0 to 3) of pixel;

    signal color_out:   scan :=  ( (X"FF", X"A0", X"FF"), 
                                   (X"7F", X"7F", X"7F"),
                                   (X"00", X"FF", X"00"), 
                                   (X"C0", X"C0", X"C0") );
begin

Verify_data_process : 
    process
        variable my_line:  line; 
        file l_file:       TEXT;   -- open write_mode is "color_out.txt";
        constant header:    string := "  R   G   B";
        variable file_is_open:  boolean;
    begin -- process
        if not file_is_open then
            file_open (l_file, "color_out.txt", write_mode);
            file_is_open := true;
            -- print(l_file, "R G B" );
            write(my_line, header);
            writeline(l_file, my_line);
        end if;
        wait until rising_edge(clk128_tb ); --  wait until clk128_tb = '1';
        -- print(l_file, "R G B" );

        if color_out_v = '1' then
            report "Color_out";
            write(my_line, integer'image(to_integer(color_out(0).R)) & " ");
            write(my_line, integer'image(to_integer(color_out(0).G)) & " ");
            write(my_line, integer'image(to_integer(color_out(0).B)));
            writeline(l_file, my_line);
            report "write line";
        end if;
        -- file_close(l_file);
    end process;

CLOCK:
    process
    begin
        wait for 10 ns;
        clk128_tb <= not clk128_tb;
        if now > 100 ns then
            wait;
        end if;
    end process;
STIMULIS:
    process
    begin
        wait for 20 ns;
        color_out_v <= '1';
        wait;
    end process;
end architecture;

更改包括仅打开文件一次而不是显式关闭它。当模拟结束时文件将被隐式关闭,或者如果提供了敏感度列表,则可以向进程传递信号以显式关闭文件。例如,当 now = TIME'HIGH 时,可以通过交易提供信号。

同样没有名为 print 的过程,它已被一个常量标题字符串替换为写入行缓冲区和写入行。请注意,这只会在文件打开时发生一次。

rising_edge 函数的使用是习惯的力量。如果没有 MCVe,代码会自然增长。

正如 A. Kieffer 所评论的那样,使用整数'图像加上一些添加的格式空间作为答案。行是对字符串的访问(指针),您将字符串写入一行。

当运行时,上面给出了控制台输出:

ghdl -r 颜色输出
color_out.vhdl:45:13:@30ns:(报告说明): Color_out
color_out.vhdl:50:13:@30ns:(报告说明): 写行
color_out.vhdl:45:13:@50ns:(报告说明): Color_out
color_out.vhdl:50:13:@50ns:(报告说明): 写行
color_out.vhdl:45:13:@70ns:(报告说明): Color_out
color_out.vhdl:50:13:@70ns:(报告说明): 写行
color_out.vhdl:45:13:@90ns:(报告说明): Color_out
color_out.vhdl:50:13:@90ns:(报告说明): 写行
color_out.vhdl:45:13:@110ns:(报告说明): Color_out
color_out.vhdl:50:13:@110ns:(report note): write line

并且文件 color_out.txt 包含:

  R   G   B
255 160 255
255 160 255
255 160 255
255 160 255
255 160 255

color_out_v = '1' 时每个上升沿事件的一组像素值。并且在局部静态索引为 0 的情况下,它们始终是相同的像素。

所以问题是每次唤醒进程时重复打开和关闭文件。

文件关闭后的 file_open 具有清除文件内容的效果,您不会有任何结果。

参见 IEEE Std 1076-2008 5.5.2 文件操作第 2 段(摘录):

—如果提供给 Open_Kind 参数的值为 WRITE_MODE,则文件对象的访问模式为只写。此外,外部文件最初为空。写入文件对象的值按照写入的顺序放置在外部文件中。

【讨论】:

    【解决方案2】:

    我无法发表评论,因此我将其发布为答案。 像 Matthew 一样,我没有看到任何“编码问题”。尽管您正在将整数写入您的行。尝试将它们转换为字符串,这可能是问题。

    您可以使用此功能,例如:

    FUNCTION to_string (value : integer) RETURN string IS
    
    BEGIN
    
    RETURN integer'image(value);
    
    END FUNCTION to_string;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-12-12
      • 2013-09-24
      • 2018-08-19
      • 1970-01-01
      • 1970-01-01
      • 2015-11-29
      • 1970-01-01
      相关资源
      最近更新 更多