简体   繁体   English

如何管理大型VHDL测试平台

[英]How to manage large VHDL testbenches

One problem I've seen again and again on different VHDL projects is that the top-level testbenches are always large and difficult to keep organized. 我在不同的VHDL项目中一次又一次看到的一个问题是,顶级测试平台总是很大并且很难保持井井有条。 There is basically a main test process where EVERY test signal is controlled or validated from, which becomes HUGE over time. 基本上有一个主要的测试过程,其中每个测试信号都被控制或验证,随着时间的推移变得巨大。 I know that you can make testbenches for the lower-level components, but this question mainly applies to top-level input/output tests. 我知道您可以为较低级别的组件制作测试平台,但这个问题主要适用于顶级输入/输出测试。

I'd like to have some kind of hierarchy structure to keep things organized. 我希望有某种层次结构来保持组织有序。 I've tried implementing VHDL procedures, but the compiler was very unhappy because it thought I was trying to assign signals from different sections of code... 我已经尝试过实现VHDL程序,但编译器非常不满意,因为它认为我试图从不同代码段分配信号......

Is there anything available in VHDL to achieve the behavior of c programming's inline-function or #define preprocessor replacement macros? VHDL中是否有可用于实现c编程的内联函数或#define预处理器替换宏的行为? If not, what can you suggest? 如果没有,你能提出什么建议? It would make me happy to be able to have my top-level test bench look like this: 能让我的顶级测试平台看起来像这样会让我高兴:

testClockSignals();
testDigitialIO();
testDACSignals();
...

Having the implementation of these functions in a separate file would be icing on the cake. 在单独的文件中实现这些功能将是锦上添花。 Haha...I'd just like to write and simulate the test benches in C. 哈哈......我只想在C中编写和模拟测试台。

It is a VHDL requirement that the either you write the procedures in the process (as @MortenZdk suggests) or you pass all the IO to it. 您要么在流程中编写过程(如@MortenZdk建议),要么将所有IO传递给它,这是VHDL要求。

My preference is to put my procedures only in packages, so I use the pass all IO approach. 我的偏好是只将我的程序放在包中,所以我使用pass all IO方法。 To simplify what is passed, I use records. 为了简化传递的内容,我使用记录。 If you reduce it to one record, it will be inout and require resolution functions on the elements of the record. 如果将其减少到一个记录,它将是inout并且需要对记录元素进行解析功能。

For more ideas on this approach, goto: http://www.synthworks.com/papers/ and see the papers titled: "Accelerating Verification Through Pre-Use ..." (near the bottom) and " VHDL Testbench Techniques that Leapfrog SystemVerilog" (at the top) 有关这种方法的更多想法,请转到: http//www.synthworks.com/papers/并查看标题为“通过预先使用加速验证...”(靠近底部)和“跳跃式的VHDL测试平台技术”的论文SystemVerilog“(在顶部)

Another key aspect is to use a separate process for each independent interface. 另一个关键方面是为每个独立接口使用单独的进程。 This way stimulus can be generated concurrently for different interfaces. 这种方式可以针对不同的接口同时生成刺激。 This is also illustrated in the papers. 这也在论文中说明。

Separating test bench code in manageable procedures is possible, but maybe the compiler complained because a procedure tries to access signals that were not in scope ? 在可管理的程序中分离测试台代码是可能的,但也许编译器抱怨,因为程序试图访问不在范围内的信号? If a procedure is to controls a signal that is not in scope, then the signal can be given as argument to the procedure, as shown for the procReset example below. 如果一个过程是控制一个不在范围内的信号,那么该信号可以作为过程的参数给出,如下面的procReset示例所示。

A test bench structure, with multiple levels for easier maintenance, is shown below: 具有多级以便于维护的测试台结构如下所示:

--==========================================================
-- Reusable procedures

-- Reset generation
procedure procReset(signal rst : out std_logic; ...) is
...

--==========================================================
-- Main test control procedure in test bench
process is

  ------------------------------------------------------------
  -- General control and status

  -- Reset device under test and related test bench modules
  procedure genReset is
  begin
    procReset(rst, 100 ns);  -- procReset declared elsewhere
    -- Other code as required for complete reset
  end procedure;

  ------------------------------------------------------------
  -- Test cases

  procedure testClockSignals is
  begin
    genReset;  -- Apply reset to avoid test case interdependency
    -- Test code here, and call genErr if mismatch detected
  end procedure;

  procedure testDigitialIO is
  begin
    genReset;  -- Apply reset to avoid test case interdependency
    -- Test code here, and call genErr if mismatch detected
  end procedure;

  procedure testDACSignals is
  begin
    genReset;  -- Apply reset to avoid test case interdependency
    -- Test code here, and call genErr if mismatch detected
  end procedure;

begin

  ------------------------------------------------------------
  -- Run test cases
  testClockSignals;
  testDigitialIO;
  testDACSignals;
  -- End of simulation
  std.env.stop(0);
  wait;

end process;

There are several levels in the structure: 结构中有几个级别:

  1. Run test cases: Where the procedures for each test case is called. 运行测试用例:调用每个测试用例的过程。 It is thereby possible to comment out one or more of the test cases during development and debugging. 由此可以在开发和调试期间注释掉一个或多个测试用例。

  2. Test cases: Test test case code itself, which is written as separate and independent procedures. 测试用例:测试测试用例代码本身,它是作为独立和独立的程序编写的。 Interdependence between run of the different test cases is avoided by reset (using genReset procedure) of the device under test and related test bench support modules. 通过重置(使用genReset过程)被测设备和相关的测试台支持模块,可以避免不同测试用例运行之间的相互依赖性。

  3. General control and status: Reusable test bench specific procedure, for example reset of device under test and test bench support modules. 一般控制和状态:可重复使用的测试台特定程序,例如重置被测设备和测试台支持模块。

  4. Reusable procedures: Does not control or use test bench signals directly, but only through procedure arguments. 可重复使用的程序:不直接控制或使用测试台信号,而只是通过程序参数。 These procedures may be located in packages (other files) for reuse in other test benches. 这些过程可以位于包(其他文件)中,以便在其他测试平台中重用。

The test bench file may still be quite a number of lines, since all the test case code still have to be in the same file with the above approach, if this test bench code need direct access to test bench signals in order to control or check the signals values. 测试平台文件可能仍然是相当多的行,因为所有测试用例代码仍然必须与上述方法在同一文件中,如果此测试工作台代码需要直接访问测试台信号以便控制或检查信号值。 If signal values can be passed to test case procedures through arguments, as done for the procReset call, then it is possible to move the test case code to another package. 如果信号值可以通过参数传递给测试用例过程,就像procReset调用一样,那么就可以将测试用例代码移动到另一个包中。

If you have lower level testbenches for each block, then you can make use of them at the top level. 如果每个块都有较低级别的测试平台,那么您可以在顶层使用它们。

By making the key lower level test elements entities in their own right, you can compose them into higher level test items which are often just a small shim to convert the pin-level data into the test-level data you were originally using. 通过将关键的较低级别测试元素实体放在自己的右侧,您可以将它们组合成更高级别的测试项目,这些测试项目通常只是一个小的垫片,可以将引脚级数据转换为您最初使用的测试级数据。

For example, in an image processing FPGA, you would have some image-sourcing and data-checking code to check out the algorithmic parts. 例如,在图像处理FPGA中,您可以使用一些图像源和数据检查代码来检查算法部分。 These could be used as is, or with some wrapping to provide the data to the top-level FPGA pins, and then decode the pin outputs back to the format that the original checking code requires. 这些可以按原样使用,或者通过一些包装将数据提供给顶层FPGA引脚,然后将引脚输出解码回原始检查代码所需的格式。

The register setup code that was no doubt tested at the lower level, can be wrapped in some more code with wiggles the FPGA pins appropriately and interprets the pin-wiggling results. 毫无疑问,在较低级别测试的寄存器设置代码可以包含在更多代码中,并且适当地摆动FPGA引脚并解释引脚摆动结果。

The combination of the two sets of code allows you to check the end-to-end function of the image processing pipeline and the register configuration of that pipeline. 两组代码的组合允许您检查图像处理管道的端到端功能和该管道的寄存器配置。

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

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