Xilinx шаблон модуля на VHDL та TestBench для тестування
Інтерес до теми ПЛІС зростає постійно, але поріг входження високий. Навіть купівля дорогої налагоджувальної плати мало рятує ситуацію, оскільки для вивчення 80% матеріалів не потрібна налагоджувальна плата. Процес створення модулів для тестування представляє серйозну проблему для новачків і вимагає багато часу та зусиль для подолання порогу входження. Крім того, знайомство з моделюванням дозволить на практиці ознайомитися зі створенням і роботою цифрових пристроїв без додаткових витрат.
Мета статті заповнити цей пробіл і по кроках показати процес створення зв'язки Цільовий модуль => Тестбенч. Проекти роблю на мові VHDL у САПР Vivado від Xilinx.
1. Створення проекту
Стартова сторінка Vivado. Створюємо наш майбутній проект. У імені проекту не повинно бути російських букв і повний адреса повинна бути не більшою за 255 символів.
Створюємо проект
Вказуємо місце розташування проекту
Вибираємо RTL проект
Нічого не додаємо в проект
Вибираємо нашу цільову ПЛІС. У даному випадку я вибрав ПЛІС, яка стоїть на налагоджувальній платі Digilent Basys 3.
Підтверджуємо створення проекту.
Створений проект
Додаємо в проект основний модуль, який потім планується завантажити в FPGA. Для цього натискаємо на значок "+" в вікні Sources
Вводимо назву нашого модуля
Підтверджуємо додавання основного модуля.
Додаємо модуль для testbench.
Вводимо назву для testbench
Підтверджуємо додавання нашого testbench
Для того, щоб testbench запустився при симуляції, необхідно його зробити Top.
Для цього натискаємо правою кнопкою миші і вибираємо в меню Set as Top
В результаті отримаємо таке вікно
Після вставки коду у файли invertor і testbench отримаємо наступний вигляд проекту
2. Написання основного модуля і тестбенча для нього
При роботі з ПЛІС можна розділити проект на цільові модулі та модулі для тестування, ще їх називають testbench. Без testbench неможливо вивчати мови HDL і стандартні конструкції проектування схем. Наведу шаблон для симуляції генерації тактування і підключення модуля invertor.
Напишемо простий модуль для основного модуля invertor, який інвертує вхідний сигнал на мові VHDL. Коментарі починаються після двох тире "- -". Кожен модуль знаходиться у своєму файлі.
library IEEE; use IEEE.STD_LOGIC_1164.ALL; -- Розкоментуйте наступну декларацію бібліотеки, якщо використовуєте -- арифметичні функції з Signed або Unsigned значеннями --use IEEE.NUMERIC_STD.ALL; -- Розкоментуйте наступну декларацію бібліотеки, якщо інстанціюєте -- будь-які Xilinx leaf cells у цьому коді. --library UNISIM; --use UNISIM.VComponents.all; --// опис цільового модуля entity invertor is Port ( a:in std_logic; --// вхідний сигнал b:out std_logic -- // вихідний сигнал ); end invertor; --// реалізація модуля architecture Behavioral of invertor is begin b<= not a; -- // інверсія вхідного сигналу end Behavioral;
Entity - це такий чорний ящик, який має входи та виходи, а Architecture - це реалізація логіки цього чорного ящика. Завдяки умовному синтезу, у одного ящика може бути безліч реалізацій. Коли ми позначаємо Top, значить, ми вибрали основний чорний ящик, в який ми будемо кладти інші чорні ящики і з'єднувати їх сигналами.
Нижче наведений текст testbench для модуля симуляції тактового сигналу з частотою в 100 MHz.
library IEEE; use IEEE.STD_LOGIC_1164.ALL; -- Розкоментуйте наступну декларацію бібліотеки, якщо використовуєте -- арифметичні функції з Signed або Unsigned значеннями use IEEE.NUMERIC_STD.ALL; -- Розкоментуйте наступну декларацію бібліотеки, якщо інстанціюєте -- будь-які Xilinx leaf cells у цьому коді. --library UNISIM; --use UNISIM.VComponents.all; --// для тестбенча зовнішніх портів не потрібно entity testbench is -- Port ( ); end testbench; --// реалізація архітектури architecture Behavioral of testbench is --// підключення компонента invertor component invertor Port ( a:in std_logic; b:out std_logic ); end component; --// ініціалізація внутрішніх сигналів signal clk: std_logic:='1'; -- // початкове значення для тактування constant period:time:=10 ns; --// Період частоти тактування симуляції 100MHz signal output: std_logic; --// вихід інвертованого сигналу begin --// Симуляція тактування clock_gen: process begin loop --// початок безкінечного циклу clk<=not clk; --// інверсія тактування wait for period/2; --// очікування часу end loop; --// кінець безкінечного циклу end process; --// створюємо екземпляр компонента, для якого example: invertor port map( a=>clk, --// асоціюємо тактовий сигнал з входом а b=>output --// асоціюємо вихідний сигнал з виходом b ); end Behavioral;
Для testbench у entity немає портів входу і виходу, оскільки по суті це і є наша ПЛІС. Оскільки це найголовніший чорний ящик, тому ми його і налаштовуємо як Top. Тактування ми симулюємо в блоці clock: process. Для того, щоб інверсія працювала, потрібно не забути у початкового сигналу при ініціалізації задати початкове значення '0' або '1', оскільки за замовчуванням логічний рівень невідомий. Для того, щоб підключити наш модуль, який ми збираємося тестувати, необхідно спочатку підключити його реалізацію, а далі ми створюємо екземпляри і асоціюємо його входи та виходи з сигналами від інших модулів.
Після того, як ми підключили тестований екземпляр до тактування, можна натиснути на кнопку Run Simulation, отримаємо наступну картину симуляції
Як бачимо, вихід інвертований відносно тактового сигналу.
В статті я намагався по кроках показати весь шлях створення проекту, розробки шаблону основного модуля і testbench для перевірки його роботи. Я не став зупинятися на описі конструкцій мови VHDL, компенсуючи це коментарями.
Прикріплені файли:
- clock_test.rar (47 Кб)