GHDL挂起运行测试平台

时间:2013-07-25 07:58:54

标签: vhdl fpga ghdl

在VHDL中测试简单的生命游戏实现时,在打印出“测试结束”消息后,空测试平台的GHDL模拟会以100%的CPU使用率挂起。

以下是代码:

----- Package ------------------------------
library ieee;
use ieee.std_logic_1164.all;

package data_types is
    type array2D is array (0 to 10, 0 to 10) of std_logic;
end data_types;


----- Main Code ----------------------------
library ieee;
use ieee.std_logic_1164.all;
use work.data_types.all;

entity de0 is
    port (matrix : inout array2D);
end de0;


architecture life of de0 is

    -- Return the integer value of a cell, treating all out of bounds as 0
    function cellValue (matrix : array2D; x, y : integer) return integer is 
    begin
        if (y < 0 or y > matrix'high(1) or x < 0 or x > matrix'high(2) or matrix(y, x) = '0') then
            return 0;
        else
            return 1;
        end if;
    end cellValue;

begin

    -- Iterate over all cells
    row: for y in matrix'range(1) generate
        column: for x in matrix'range(2) generate

            process

                variable neighbours : integer := cellValue(matrix, x - 1, y - 1) +
                                                cellValue(matrix, x - 1, y) +
                                                cellValue(matrix, x - 1, y + 1) +
                                                cellValue(matrix, x, y - 1) +
                                                cellValue(matrix, x, y + 1) +
                                                cellValue(matrix, x + 1, y - 1) +
                                                cellValue(matrix, x + 1, y) +
                                                cellValue(matrix, x + 1, y + 1);

            begin

                -- Update the cell value according to the game of life rules
                if (neighbours = 2 or neighbours = 3) then
                    matrix(y, x) <= '1';
                else
                    matrix(y, x) <= '0';
                end if;

            end process;

        end generate;
    end generate;

end life;

测试平台:

library ieee;
use ieee.std_logic_1164.all;
use work.data_types.all;

entity life_tb is
end life_tb;

architecture behaviour of life_tb is
    component life
        port (matrix : inout array2D);
    end component;

    for test: life use entity work.de0;
    signal matrix : array2D;

begin

    test: life port map (matrix => matrix);

    process
    begin
            assert false
                report "End of test" severity note;

            wait;

    end process;
end behaviour;

2 个答案:

答案 0 :(得分:4)

这补充了MortenZdk的好答案。它只是太大而无法发表评论而且不会改变答案。它确实演示了如何使您的模型计时以及如何阻止它连续运行。

放置矩阵是de0(生命)

中未标记过程的敏感性列表
            process (matrix)

给出:

ghdl -a de0.vhdl
ghdl -a life_tb.vhdl
ghdl -e life_tb
ghdl -r life_tb
life_tb.vhdl:22:13:@0ms:(assertion note): End of test

断言测试只执行一次并立即执行,它不表示测试结束。

请注意模型退出执行但我们不知道它可能会如何进行模拟循环。模拟时间背后的想法是允许存储波形以及要量化的相对时间。

为模拟添加时钟:

在架构声明区域中,我们声明了时钟信号:

    signal clk: std_logic;

您可以添加新流程以在测试平台中生成时钟(life_tb.vhdl):

CLOCK:
    process 
    begin
        wait for 10 ns;
        clk <= '0';
        wait for 10 ns;
        clk <= '1';
    end process;

它的周期为20 ns,第一个上升沿为模拟中的10 ns。

我们将时钟添加到生活端口:

    component life
        port (
            matrix :    inout   array2D;
            clk:        in      std_logic
    );
    end component;

我们更新de0实体以使用clk:

entity de0 is
port (
    matrix : inout array2D;
    clk:      in   std_logic
);

我们将流程更新为对clk敏感并定时:

            process (clk)

            variable neighbours : integer := cellValue(matrix, x - 1, y - 1) +
                                            cellValue(matrix, x - 1, y) +
                                            cellValue(matrix, x - 1, y + 1) +
                                            cellValue(matrix, x, y - 1) +
                                            cellValue(matrix, x, y + 1) +
                                            cellValue(matrix, x + 1, y - 1) +
                                            cellValue(matrix, x + 1, y) +
                                            cellValue(matrix, x + 1, y + 1);

        begin
            if clk'event and clk = '1' then
            -- Update the cell value according to the game of life rules
                if (neighbours = 2 or neighbours = 3) then
                    matrix(y, x) <= '1';
                else
                    matrix(y, x) <= '0';
                end if;
            end if;

现在因为clk是一个自由运行的振荡器,我们需要使用停止时间:

ghdl -a de0.vhdl
ghdl -a life_tb.vhdl
ghdl -e life_tb
ghdl -r life_tb --stop-time=100ns --wave=life_tb.ghw
life_tb.vhdl:35:13:@0ms:(assertion note): End of test
ghdl:info: simulation stopped by --stop-time

clocked life simulation

如果滚动maxtrix元素,我们会发现矩阵的四个角在第一个时钟事件中设置为“1”。所有剩余的元素都设置为'0'。

光标处显示的第二个clk事件不会为任何矩阵元素分配新值(四个矩阵角每个都看到三个邻居,它们是稳定的)。

如果矩阵在过程灵敏度列表中,则模拟将在第二次(非时钟)后停止。

定时模拟的关键在于它允许您通过检查波形来查看模拟,在本例中使用gtkwave。替代方案是断言和/或报告语句,但在非定时模拟中,这些将发生在循环边界上,如果它们不是同一过程中的顺序语句,则无法保证顺序。

除了在测试平台中评估matrix'event的断言语句之外,您可以在不修改原始代码的情况下注意,您可以让模型停止模拟。您希望使用运行时选项更改停止模拟的阈值(例如--assert-level = warning,其中缺少matrix'event的断言是警告。(并且断言将表示实际结束)测试)。

修复cellValue正如他们所说的那样,练习留给了读者。 (至于如何或为什么首先设置矩阵角?)

有趣的部分是告诉您的模型何时定时静止。您可以使用matrix'event切换信号(将其用作时钟)并使用时钟测试该信号的相同值的两次连续出现。当然,信号可以在断言语句中使用,断言级别在静止时结束模拟。

可合成的硬件涉及更多。

答案 1 :(得分:3)

de0的生命过程既没有敏感列表也没有wait语句,所以这个过程将永远运行,只是在相同的模拟时间以无限循环执行过程中的语句,因此模拟不会停止。

您可以通过添加敏感度列表(matrix)或等待一些条件来解决此问题。