这似乎是一个使用同一实体的多个架构会有所帮助的示例。你有一个文件如下:
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_SENSORS、SPI_CS_CPU、SPI_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 选择的架构来更改测试。
使用配置
如果您有很多不同的测试,您可以使用配置来更轻松地选择它们。为此,您首先需要使测试控制实体实例化使用组件声明而不是直接实例化。然后,在每个测试控制架构文件的末尾,创建配置:
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 之类的命令。这样可以更轻松地管理包含大量不同测试的测试台,因为您无需编辑任何文件即可运行它们。