Как создать самопроверяющийся тестбенч в VHDL — практическое руководство
Самопроверяющийся тестбенч — это VHDL-программа, которая проверяет корректность устройства под тестом (DUT) без ручного вмешательства. После выполнения он автоматически сообщает статус OK или Failed, что делает его незаменимым инструментом для надежной VHDL-разработки.
У каждого VHDL-модуля должен быть связанный самопроверяющийся тестбенч. Это гарантирует, что любое изменение — будь то в самом DUT, в подмодуле или в интерфейсе — не введет регрессий молча. Хорошо спроектированный тестбенч — первая линия обороны против тонких ошибок.
Устройство под тестом
Мы будем использовать простой, но наглядный DUT: преобразователь двоичного кода в код Грея. Ниже приведена полная RTL-реализация.
library ieee; use ieee.std_logic_1164.all; entity gray_converter is port ( bin : in std_logic_vector; gray : out std_logic_vector ); end gray_converter; architecture rtl of gray_converter is begin process(bin) is begin gray(gray'high) <= bin(bin'high); for i in bin'high - 1 downto bin'low loop gray(i) <= bin(i + 1) xor bin(i); end loop; end process; end architecture;
Код Грея — это схема двоичного кодирования, где между последовательными значениями меняется только один бит, минимизируя вероятность ошибок в последовательной связи и цифровых счетчиках. Таблица ниже демонстрирует соответствие для 4-битных значений.
| Десятичный | Двоичный | Код Грея |
|---|---|---|
| 0 | 0000 | 0000 |
| 1 | 0001 | 0001 |
| 2 | 0010 | 0011 |
| 3 | 0011 | 0010 |
| 4 | 0100 | 0110 |
| 5 | 0101 | 0111 |
| 6 | 0110 | 0101 |
| 7 | 0111 | 0100 |
| 8 | 1000 | 1100 |
| 9 | 1001 | 1101 |
| 10 | 1010 | 1111 |
| 11 | 1011 | 1110 |
| 12 | 1100 | 1010 |
| 13 | 1101 | 1011 |
| 14 | 1110 | 1001 |
| 15 | 1111 | 1000 |
Скелет тестбенча
Ниже приведен минимальный тестбенч, инстанцирующий DUT и объявляющий необходимые сигналы. Обратите внимание на включение std.env.finish, возможности VHDL-2008, которая чисто завершает симуляцию.
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use std.env.finish; entity gray_converter_tb is end gray_converter_tb; architecture sim of gray_converter_tb is signal bin : std_logic_vector(3 downto 0) := (others => '0'); signal gray : std_logic_vector(3 downto 0); DUT : entity work.gray_converter(rtl) port map ( bin => bin, gray => gray ); end architecture;
Если вы компилируете этот файл в VHDL-2008 совместимом симуляторе, таком как ModelSim, вам может понадобиться установить версию языка файла на 2008. В ModelSim нажмите правой кнопкой на файл, выберите Properties → VHDL → Use 1076‑2008.
Генерация исчерпывающих входов
Следующий шаг — создать полный перебор всех возможных 4-битных значений. Исчерпывающий тест предпочтителен, потому что гарантирует, что каждый граничный случай задействован.
PROC_SEQUENCE : process begin -- Iterate over every 4‑bit value for i in 0 to 2**bin'length - 1 loop bin <= std_logic_vector(to_unsigned(i, bin'length)); wait for 10 ns; end loop; -- Wrap‑around to the initial state bin <= (others => '0'); wait for 10 ns; report "Test: OK"; finish; end process;
Задержка 10 нс произвольна; любое положительное значение подходит, потому что DUT чисто комбинационный. Оператор finish в конце корректно завершает симуляцию.
Проверка выхода DUT
Простое вывод «Test: OK» было бы бессмысленным, если бы выход был неверным. Чтобы обеспечить корректность, мы сравниваем выходной код Грея DUT с фундаментальным свойством кода Грея: последовательные выходы должны отличаться ровно в одном бите.
PROC_CHECKER : process variable prev : std_logic_vector(gray'range); variable count : integer; begin wait on bin; prev := gray; -- Allow combinational logic to resolve wait for 1 ns; count := 0; for i in gray'range loop if gray(i) /= prev(i) then count := count + 1; end if; end loop; assert count = 1 report integer'image(count) & " bits changed, should have been 1" severity failure; end process;
Этот процесс отслеживает изменения на bin, захватывает предыдущий выходной код Грея, ждет разрешения, считает отличающиеся биты и утверждает, что счетчик равен точно одному. Если утверждение проваливается, симулятор немедленно останавливается, предотвращая появление сообщения «Test: OK».
Запуск тестбенча
В ModelSim запустите симуляцию и выполните run -all. Успешный запуск завершается с:
VSIM 1> run -all # ** Note: Test: OK # Time: 170 ns Iteration: 0 Instance: /gray_converter_tb
Тестирование надежности тестбенча
Чтобы подтвердить, что проверка обнаруживает ошибки, временно введите ошибку в DUT — например, зафиксируйте gray(3) в ноль.
process(bin) is begin gray(gray'high) <= bin(bin'high); for i in bin'high - 1 downto bin'low loop gray(i) <= bin(i + 1) xor bin(i); end loop; -- Emulate a stuck‑at‑zero fault gray(3) <= '0'; end process;
Запуск тестбенча теперь вызывает сбой утверждения, отображая точное количество изменившихся бит:
VSIM 2> run -all # ** Failure: 0 bits changed, should have been 1 # Time: 81 ns Iteration: 0 Process: /gray_converter_tb/PROC_CHECKER File: gray_converter_tb.vhd # Break in Process PROC_CHECKER at ray_converter_tb.vhd line 61
Начало работы с самопроверяющимися тестбенчами
Привыкайте писать самопроверяющиеся тестбенчи для каждого VHDL-модуля. Они экономят время, выявляя регрессии рано, и предоставляют четкую запись намерения дизайна. Хотя тестбенчи не должны быть синтезируемыми, они должны быть понятными, поддерживаемыми и использовать новейшие конструкции VHDL для читаемости и эффективности.
Для более глубокого обучения рассмотрите продвинутые курсы, охватывающие полный цикл дизайна — от спецификации до прототипа FPGA — с акцентом на строгие практики верификации.
Обновлено 12 октября 2020: Я завершил курс по VHDL и FPGA. Нажмите на изображение ниже, чтобы узнать больше.
Узнайте больше о курсе Dot Matrix VHDL и FPGA здесь!
Открытие:
Будет решено позже.
VHDL
- Создайте свой первый шаблон AWS CloudFormation — практическое руководство
- Строительство Cloud Center of Excellence: стратегии успешной миграции и успеха клиентов
- Создание стратегического плана внедрения облака
- Создание бесшовного пользовательского опыта: чертеж UX-дизайна
- Создание списков строк в VHDL: лучшие практики и пример
- Создание Tcl-управляемого тестбенча для VHDL-модуля кодового замка
- Корректное завершение симуляции VHDL-тестбенча
- Реализация динамического связного списка в VHDL с защищенными типами и указателями доступа
- Строительство гуманоцентричных умных городов: стратегический блупринт
- Создание массива объектов в Java: пошаговое руководство