单个实体的多种行为

Multiple behaviours for single entity

我写了一个 VHDL Testbench,其中包含以下内容:

一切都很好,除了我想要两种不同类型的刺激(假设是一种简单的刺激和一种更复杂的刺激),所以我所做的是创建了两个测试台,除了主要的刺激外,它们都有共同点大过程。 但是我觉得这不是很方便,因为我总是需要更新两者,例如,当我对 UUT 端口映射进行更改时。不酷。

我真的不想合并我的两个主要进程,因为它看起来很糟糕,而且我不能在同一架构中同时声明这两个进程(我可能会得到一个很长的文件并且我不喜欢他们理论上可以访问相同的信号)。

所以我真的很想保留 "distinct files" 方法,但仅限于该特定过程。有办法解决这个问题还是我注定要失败?

这似乎是一个示例,其中使用同一实体的多个架构会有所帮助。您有一个文件:

entity TestBench
end TestBench;

architecture SimpleTest of TestBench is
    -- You might have a component declaration for the UUT here
begin
    -- Test bench code here
end SimpleTest;

您可以轻松添加另一个架构。您可以在单独的文件中拥有体系结构。您还可以使用直接实体实例化来避免 UUT 的组件声明(如果 UUT 更改,则所需的工作减半):

architecture AnotherTest of TestBench is
begin
    -- Test bench code here
    UUT : entity work.MyDesign (Behavioral)
    port map (
        -- Port map as usual
    ); 
end AnotherTest ;

这不会保存重复代码,但至少它删除了一个端口映射列表。

如果您的 UUT 端口映射中有很多信号,还有一点是,如果您尝试将更多信号转化为矢量,这会更容易。例如,您可能有很多相同类型的串行输出到电路板上的不同芯片。我看到很多人会把它们命名为 SPI_CS_SENSORSSPI_CS_CPUSPI_CS_FRONT_PANEL 等。我发现如果将它们组合成 SPI_CS (2 downto 0) 会使 VHDL 更易于管理,通过电路图指定的信号映射到什么设备。我想这只是偏好,但如果您有非常大的端口列表,这种方法可能会有所帮助。

使用 TestControl 实体

更复杂的方法将涉及使用测试控制实体来实施所有刺激。在最简单的层面上,这将具有来自您感兴趣的 UUT 的所有信号作为端口。更复杂的测试台将具有带有接口的测试控制实体,该接口可以控制总线功能模型,其中包含练习所需的实际引脚摆动你的设计。你可以有一个文件声明这个实体,比如说 TestControl_Entity.vhd:

entity TestControl is
port (
    clk : out std_logic;
    UUTInput : out std_logic;
    UUTOutput : in std_logic
);

那么你有一个或多个架构文件,例如TestControl_SimpleTest.vhd:

architecture SimpleTest of TestControl is
begin
    -- Stimulus for simple test
end SimpleTest;

您的顶级测试平台将类似于:

entity TestBench
end TestBench;

architecture Behavioral of TestBench is
    signal clk : std_logic;
    signal a : std_logic;
    signal b : std_logic;
begin

    -- Common processes like clock generation could go here

    UUT : entity work.MyDesign (Behavioral)
    port map (
        clk => clk,
        a => a,
        b => b
    ); 

    TestControl_inst : entity work.TestControl (SimpleTest)
    port map (
        clk => clk,
        UUTInput => a,
        UUTOutput => b
    ); 
end SimpleTest;

您现在可以通过更改 TestControl 的体系结构 select 来更改测试。

使用配置

如果您有很多不同的测试,您可以使用配置来简化 select 它们。为此,您首先需要使测试控件实体实例化使用组件声明而不是直接实例化。然后,在每个测试控制架构文件的末尾,创建配置:

use work.all;

configuration Config_SimpleTest of TestBench is
    for Behavioral
        for TestControl_inst : TestControl
            use entity work.TestControl (TestControl_SimpleTest);
        end for;
    end for;
end Config_SimpleTest;

现在当你想模拟时,你模拟了一个配置,所以你会 运行 像 sim work.Config_SimpleTest 这样的命令而不是像 sim TestBench 这样的命令。这使得管理包含大量不同测试的测试台变得更加容易,因为您不必为了 运行 它们而编辑任何文件。

可以将泛型添加到测试台实体中,以控制是简单还是 完成复杂的测试,例如:

entity tb is
  generic(
    test : positive := 1);  -- 1: Simple, 2: Complex
end entity;


library ieee;
use ieee.std_logic_1164.all;

architecture syn of tb is
  -- Superset of declarations for simple and complex testing
begin

  simple_g : if test = 1 generate
    process is  -- Simple test process
    begin
      -- ... Simple testing
      wait;
    end process;
  end generate;

  complex_g : if test = 2 generate
    process is  -- Complex test process
    begin
      -- ... Complex testing
      wait;
    end process;
  end generate;

end architecture;

缺点是声明不能有条件,所以 声明必须是信号和其他控件的超集 简单和复杂的测试。

模拟器可以通过选项控制泛型值,例如-G 用于 ModelSim 模拟器中的通用控制。从而可以编译 一次,并且 select 在运行时进行简单或复杂的测试。