Как создать самопроверяющийся тестовый стенд
Самопроверяющийся тестовый стенд — это программа VHDL, которая проверяет правильность тестируемого устройства (DUT), не полагаясь на то, что оператор вручную проверит выходные данные. Тестовый стенд с самопроверкой работает полностью самостоятельно и в конце выводит сообщение «ОК» или «Не удалось».
Каждый модуль VHDL должен иметь связанный тестовый стенд с самопроверкой. Важно иметь возможность в любое время убедиться, что все модули ведут себя должным образом. Например, когда вы вносите изменения в тестируемое устройство, подмодуль или интерфейсный модуль. Мы все знаем, что вещи могут сломаться, и лучшим инструментом для выявления таких проблем является тестовый стенд с самопроверкой.
Тестируемое устройство
Давайте сразу приступим к созданию примера самопроверяющегося тестового стенда. Во-первых, нам нужно что-то протестировать, DUT. Для этого я создал модуль в коде ниже. Это преобразователь двоичного кода в код Грея.
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;
Код Грея — это альтернативная схема кодирования чисел, отличная от обычного двоичного кодирования. Основное свойство и назначение кода Грея заключается в том, что при счете между соседними числовыми значениями изменяется только один бит.
Десятичный | Двоичный | Серый |
---|---|---|
0 | 0000 | 0000 |
1 | 0001 | 0001 |
2 | 0010 | 0011 |
3 | <тд>0011тд>0010 | 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 и всеми необходимыми импортами.
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); begin DUT : entity work.gray_converter(rtl) port map ( bin => bin, gray => gray ); end architecture;
Обратите внимание, что мы импортируем std.env.finish
который требует VHDL-2008. Если вы попытаетесь скомпилировать тестовый стенд в ModelSim, ничего не меняя, вы получите следующую ошибку:
# ** Warning: gray_converter_tb.vhd(6): (vcom-1516) Package "STD.ENV" does not exist in this language version.

К счастью, это можно легко исправить, установив версию VHDL для файла тестовой среды на VHDL-2008. Щелкните правой кнопкой мыши VHD-файл testbench и выберите «Свойства» → «VHDL» → «Использовать 1076-2008-> ОК».
Для DUT ничего менять не нужно. Обычно для тестовых стендов используется более высокая версия VHDL, чем для модулей RTL. Вы всегда хотите иметь возможность использовать новейшие конструкции VHDL в своем тестовом стенде, но большинство инструментов синтеза их не поддерживают.
Генерация ввода
Следующим дополнением к испытательному стенду будет процесс, генерирующий входные данные для тестируемого устройства. Всегда лучше создать исчерпывающий тест, тест, который пробует все возможные входные значения. Хотя, если перестановок слишком много, вы можете ограничиться выполнением только крайних случаев.
Вход и выход нашего тестируемого устройства имеют неопределенный диапазон. Тем не менее, я сделаю обоснованное предположение, что тестирования с векторами длиной четыре бита достаточно, чтобы выявить любую возможную проблему с этим модулем.
Приведенный ниже код содержит весь процесс создания входной последовательности.
PROC_SEQUENCE : process begin -- Test all possible input values 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; -- Finally, test the wrapped value bin <= (others => '0'); wait for 10 ns; report "Test: OK"; finish; end process;
Первый фрагмент кода представляет собой цикл For, который генерирует последовательность подсчета от наименьшего возможного значения до максимально возможного значения. Между значениями мы ждем 10 наносекунд, чтобы тестируемое устройство среагировало. Хотя сработало бы любое значение наносекунды больше 0, потому что логика внутри тестируемого устройства чисто комбинационная.
Второй фрагмент кода предназначен для проверки ситуации, когда входной счетчик возвращается к 0, что было начальным входным значением. После этого нет необходимости в дальнейшем тестировании, поскольку тестируемое устройство будет снова и снова давать одни и те же результаты.

Последние две строки кода в процессе предназначены для корректного завершения теста. Текст «Тест:ОК» выводится на консоль, а затем симуляция останавливается с помощью ключевого слова VHDL-2008 «завершить».
Обратите внимание, что если вы запустите ModelSim с кнопкой «Выполнить» по умолчанию, ModelSim предложит вам диалоговое окно выхода после успешного завершения тестового стенда. Это поведение можно изменить при запуске Vsim из скрипта или из командной строки. Добавьте переключатель «-onfinish stop» в команду Vsim, как описано в справочнике по командам ModelSim.
Проверка вывода
Теперь мы снабжаем ИУ входами, но проверка выхода вообще не производится. Тестовый стенд распечатает «Тест:ОК», независимо от того, правильный вывод или нет. Давайте что-нибудь с этим сделаем.
При создании алгоритма проверки всегда следует пытаться реализовать тест иначе, чем в тестируемом устройстве. В противном случае фундаментальный недостаток логики может остаться незамеченным, поскольку он присутствует как в тестируемом устройстве, так и в алгоритме тестового стенда.
Следуя этому принципу, мы собираемся протестировать выход ИУ, проверяя не правильность кода Грея, а то, что только один бит меняется от одного числа к другому. В конце концов, это основная причина использования кода Грея. В приведенном ниже коде показан процесс, выполняющий такую проверку.
PROC_CHECKER : process variable prev : std_logic_vector(gray'range); variable count : integer; begin wait on bin; prev := gray; -- Wait for all delta cycles to propagate wait for 1 ns; -- Count the number of changed bits 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
сигнал, вход в ИУ. Мы могли бы использовать список чувствительности с тем же результатом, но я предпочитаю использовать только операторы ожидания в коде тестового стенда. Это соглашение позволяет легко понять, имеете ли вы дело с тестовым стендом или модулем RTL, просто взглянув на то, как написан код.
В строке секунд мы копируем предыдущий вывод тестируемого устройства. Помните, что это первый дельта-цикл после bin
. сигнал изменился, и тестируемое устройство еще не может среагировать. Таким образом, можно безопасно копировать выходные данные тестируемого устройства, предполагая, что это старое значение.
Затем мы ждем 1 наносекунду, чтобы завершить всю комбинационную логику в тестируемом устройстве. Теперь выход тестируемого устройства должен быть стабильным, и мы можем безопасно проверить его значение.
В следующем фрагменте кода мы используем цикл For для подсчета количества измененных битов на выходе тестируемого устройства.
Наконец, приходит оператор Assert, который проверяет, что количество измененных битов равно 1. Операторы Assert работают, проверяя условие, в данном случае это count = 1
. . Если условие оценивается как false
, будет поднято утверждение, и симулятор остановится до того, как будет распечатано сообщение «Тест:ОК».
Целесообразно включить необязательный оператор отчета с оператором assert. Этот текст будет распечатан, если утверждение не пройдено. В нашем примере я привожу краткое объяснение события, вызвавшего сбой тестового стенда.
Запуск тестового стенда
Пришло время запустить наш тестовый стенд, чтобы убедиться, что тестируемое устройство работает правильно. После запуска симуляции в ModelSim и нажатия кнопки «run-all» мы видим, что на консоль выводится сообщение «Test:OK».
VSIM 1> run -all # ** Note: Test: OK # Time: 170 ns Iteration: 0 Instance: /gray_converter_tb
Тестирование тестового стенда
Мне всегда нравится создавать условие отказа в тестируемом устройстве, просто чтобы убедиться, что испытательный стенд работает. Иногда это происходит естественным образом из-за фактических ошибок в тестируемом устройстве во время его разработки. Но если это не так, просто создайте ошибку на короткое время, чтобы протестировать тестовый стенд.
Для этого я отредактирую код тестируемого устройства, чтобы создать ошибку «застрял на 0» в бите номер 3. После этого теста я уберу ошибку, зная, что тестовый стенд способен обнаруживать такие ошибки. В приведенном ниже коде показан процесс DUT с дополнительной строкой кода.
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 error gray(3) <= '0'; end process;
Когда мы сейчас запустим тестовый стенд, мы увидим, что тестовый стенд останавливается, и ошибка распечатывается до того, как будет достигнута строка «Test:OK». Стенограмма из консоли ModelSim показана ниже.
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-модулей. Это сэкономит вам время в долгосрочной перспективе.
При написании тестовых стендов можно проявлять творческий подход. В большей степени, чем при написании модулей RTL, потому что не все конструкции VHDL могут быть синтезированы, а тестовый стенд не обязательно должен быть синтезируемым. Ожидайте, что вы потратите на написание тестов не меньше времени, чем на написание тестируемого устройства.
Если вы хотите серьезно заняться тестированием, вам могут быть интересны мои * предстоящий курс VHDL и FPGA. В ходе курса я проведу вас через весь процесс проектирования от идеи до физического рабочего прототипа ПЛИС. Мы создадим несколько тестовых стендов с самопроверкой.
Обновлено 12 октября 2020 г.: Я закончил курс. Нажмите на изображение ниже, чтобы узнать больше.
Я научу вас лучшим методам успешного создания проектов VHDL и FPGA. Знания, которые я приобрел в течение многих лет в академических кругах и после работы инженером по оборудованию в оборонной промышленности, будут переданы вам.

Узнайте больше о курсе Dot Matrix VHDL и FPGA здесь!
Открывается:
Подлежит решению .
VHDL
- Как создать шаблон CloudFormation с помощью AWS
- Как создать облачный центр передового опыта?
- Как создать тщательно разработанную облачную стратегию
- Как создать UX без трения
- Как создать список строк в VHDL
- Как создать управляемый Tcl тестовый стенд для модуля кодовой блокировки VHDL
- Как остановить симуляцию в тестовом стенде VHDL
- Как создать связанный список в VHDL
- Как создать умные города, ориентированные на человека
- Как создать массив объектов в Java