В этой главе (перевод главы 4 даташита [1]) показывается пошаговая реализация простого дизайна PLD, начиная от создания проекта, до его процесса реализации и симуляции, в среде Xilinx ISE WebPack. Пример реализует на VHDL простой счетчик, считающий вверх и вниз, и подключенный к нему 7-сегментный индикатор. Наш дизайн изначально предназначался для CoolRunner-II CPLD. В главе 5 [1] описывается процедура реализации логики на кристалле (процесс Implemention). В других главах [1] также будет показано, как преобразовать этот готовый проект для CPLD на целевой чип Spartan-3E FPGA. Предполагается, что система разработки Xilinx ISE WebPack 14.7 у Вас уже установлена (как это делается, см. [2]).
[Создание проекта]
1. Запустите Xilinx ISE Project Navigator (именно в нем разрабатываются проекты для CPLD).
2. Для создания нового проекта выберите в меню File -> New Project. В поле "Name:" введите имя проекта. Давайте назовем проекта "Tutorial", и разместим его в папке предназначенной для Ваших проектов (предположим, это папка J:\Xilinx\Projects). При вводе имени будет автоматически создан подкаталог Tutorial, расположенный в паке проектов J:\Xilinx\Projects. В этом руководстве мы будем использовать тип дизайна HDL, поэтому в выпадающем списке "Top-level source type:" будет выбран вариант HDL (в этом случае модуль верхнего уровня может быть написан на HDL-языках VHDL или Verilog).
Рис. 4-1. Начало диалога мастера создания нового проекта (Project Wizard - Create New Project).
В поле "Description:" можно ввести произвольное описание проекта.
3. Кликните кнопку Next. В следующем окне диалога вводятся важные параметры проекта, зависящие от используемого чипа CPLD, используемой системы синтеза и используемого симулятора. Введите следующие параметры (остальные оставьте по умолчанию):
Property Name (свойство)
Value (значение)
Family (семейство микросхем логики)
CoolRunner2 CPLDs
Device (используемая микросхема)
XC2C256
Package (корпус микросхемы)
VQ100
Speed (Speed Grade, класс скорости микросхемы)
-7
Synthesis Tool (инструмент синтеза логики)
XST (VHDL/Verilog)
Simulator (симулятор)
ISE Simulator (VHDL/Verilog)
Рис. 4-2. Ввод основных свойств проекта.
В качестве стандарта языка для анализатора синтаксиса (VHDL Source Analysis Standard) должно быть выбрано VHDL-93.
4. Кликните на кнопку Next, и затем на кнопку Finish. Окно мастера нового проекта закроется, и будет создан новый проект.
5. Пока в проекте нет ни одного модуля исходного кода. Давайте добавим модуль верхнего уровня на языке VHDL. Для этого выберите в меню Project -> New Source..., откроется окно для выбора типа нового добавляемого модуля исходного кода. Выберите вариант VHDL Module, и введите для него имя clock_divide.
Рис. 4-3. Добавление нового модуля в проект.
6. Кликните кнопку Next. Откроется окно мастера создания нового модуля (New Source Wizard), где предстоит определить входы и выходы устройства, которое представляет модуль.
Мы сначала создадим модуль тактовой частоты, потому что нужно будет разделить частоту 100 кГц генератора платы (предположим, что он есть на плате) до частоты, оптимальной для переключения блока динамической индикации 7-сегментным индикатором. В принципе коэффициент деления не так важен, лишь бы в результате получилась частота переключений индикатора, чтобы мерцания не были заметны на глаз. В этом примере мы используем аппаратный делитель частоты на 16, и к нему подключим 10-битный счетчик (коэффициент деления 1024), чтобы в результате получить частоту примерно 6 Гц.
Примечание: я использовал микросхему XC2C64A, у которой нет встроенного аппаратного делителя тактовой частоты, поэтому делал счетчик/делитель на 16384 (14-битный счетчик) основе вентилей логики CPLD. Если бы использовалась микросхема XC2C256, то использование его аппаратного делителя (как показано в этом примере) позволило бы сэкономить макроячейки CPLD.
7. Итак, следующее окно диалога дает возможность задать входы и выходы создаваемого модуля. Благодаря этому автоматически будет создан шаблон кода VHDL с готовыми описаниями портов реализуемой схемы. Определите здесь 2 порта: clock_osc (in, вход счетчика/делителя) и clock_div (выход).
Рис. 4-4. Определение входов и выходов (портов) нового модуля.
8. Кликните на кнопку Next, и просмотрите результаты создания нового модуля, затем на кнопку Finish.
Entity name: clock_divide
Architecture name: Behavioral
Port Definitions:
clock_osc Pin in
clk_div Pin out
9. Будет автоматически создан и добавлен в проект новый модуль clock_divide.vhd.
Рис. 4-5. Новый добавленный модуль в окне дерева модулей проекта (Project Window).
В правой части автоматически откроется окно текстового редактора созданного модуля.
[HDL Editor]
Двойной клик на любом файле в окне Design -> Hierarchy откроет окно редактора этого модуля. Если это модуль схемы, то откроется редактор схемы (ECS), а если это модуль на языке VHDL или Verilog, то откроется окно редактора текста исходного кода (HDL Editor).
Языковой шаблон кода. Мастер по нашим установкам (определение входа и выхода) создал готовый шаблон кода на языке VHDL. Но это еще не все, есть также отличный инструмент, помогающий Вам создать код HDL - можно добавлять готовые популярные функции, такие как счетчики, мультиплексоры, декодеры и регистры сдвига. Также имеются шаблоны для создания общих операторов (таких как оператор условия "IF/THEN" и циклы "FOR"), часто использующихся в языках программирования.
Языковые шаблоны используются как справочник. Они могут быть скопированы и вставлены (copy/paste) в модуль дизайна, и затем отредактированы так, как этого хочет пользователь. Обычно Вы должны поменять ширину шины или имена сигналов, и иногда нужно также поменять поведение кода в шаблоне. Чтобы использовать шаблон:
1. Поместите курсор HDL Editor между ключевыми словами begin и end блока Behavioral.
2. Откройте шаблоны (Language Templates) кликом на кнопке с лампочкой, которая находится на панели инструментов Project Navigator.
Также можно получить доступ к шаблонам через меню Edit -> Language Templates...
4. В правой части окна будет виден код выбранного шаблона. Выделите курсором мыши код счетчика от "CLK_DIV16_inst" до ");", скопируйте его и вставьте в модуль clock_divide.vhd. Также нужно поменять имена входных сигналов (см. ниже рис. 4-7).
Обратите внимание на цветовую подсветку синтаксиса кода. Зеленый цвет показывает комментарии. В этом шаблоне закомментированный текст дает подсказку о том, какие библиотеки нужны в заголовке модуля VHDL. В данном случае нужно добавить библиотеку UNISIM.vcomponents.all, для этого раскомментируйте 2 соответствующие строки в заголовке модуля clock_divide.vhd (удалите в начале строк дефисы --, обозначающие комментарий).
5. Если шаблоны Вам больше не нужны, то можно их закрыть, кликнув мышью на крестик закладки Language Templates. Закладка расположена в справа внизу, под окном редактора. Закладки - быстрый способ перемещаться по открытым окнам среди разработки ISE WebPack.
1. Теперь нам нужно создать 10-битный счетчик, чтобы дополнительно поделить частоту. Откройте снова шаблоны, и найдите соответствующий шаблон по следующему пути: VHDL -> Synthesis Constructs -> Coding Examples -> Counters -> Binary -> Up Counters -> Simple Counter.
Примечание: обратите внимание, что в прошлый раз мы начинали выбор из раздела VHDL -> Device Primitive Instantiation, а второй раз из раздела VHDL -> Synthesis Constructs. Может возникнуть вопрос - почему разделы разные? Дело тут в том, что первый раздел Device Primitive Instantiation означает реализацию делителя на основе специальных аппаратных ресурсов CPLD, а Synthesis Constructs означает реализацию обычным способом, на основе синтеза логики из макроячеек.
Вы наверное заметили, что в блоке счетчика используется ключевое слово process. Оно показывает специальную конструкцию, предназначенную для обработки какого-либо события изменения сигнала. Т. е. этот блок срабатывает только в том случае, если поменялся обрабатываемый сигнал (в нашем примере модуля clock_divide.vhd будет обрабатываться сигнал clock_div_int).
2. Скопируйте и вставьте код счетчика в файл clock_divide.vhd между операторами begin и end, после ранее вставленного кода делителя.
Нам нужно сделать несколько правок в этом коде, чтобы сделать его рабочим. Первое изменение состоит в том, чтобы поменять все три ссылки "< clock >" на "clock_div_int" и удалить угловые скобки, которые были рядом с именем "count".
3. Так как мы создали 2 новых сигнала count и clock_div_int, то нам надо декларировать их. Для этого между оператором architecture и оператором begin вставьте следующие две декларации:
signal clock_div_int :std_logic;
signal count : unsigned(9downto0):="0000000000";
Сигнал count определен как 10-битный, и ему назначено начальное нулевое значение. Эта начальная инициализация требуется для успешной симуляции. Определение count через unsigned(9 downto 0) означает, что счетчик 10-битный. Также для того, чтобы можно было использовать типы целых чисел unsigned, нужно раскомментировать строку "use IEEE.NUMERIC_STD.ALL".
4. Мы должны подключить эти 2 сигнала к 2 портам нашего делителя частоты. Отредактируйте код следующим образом:
5. И последнее, что нам нужно сделать - вывести наружу значение старшего бита счетчика count, чтобы счетчик работал как делитель частоты. Для этого после строки "end process;" и перед строкой "end Behavioral;" введите следующий оператор присваивания:
clock_div <= count(9);
Типовой модуль VHDL состоит деклараций библиотеки, блока определения входов/выходов модуля (entity), и блока описания логики модуля (architecture). Декларации библиотек нужны для того, чтобы сказать компилятору, какие нужны пакеты для компиляции кода.
У этого дизайна есть один вход (clock_osc) и один выход (clock_div). Реальная функциональное описание появляется после оператора begin в блоке architecture. Функция этого дизайна состоит в том, чтобы поделить сигнал clock_osc от генератора на 16 с использованием аппаратного делителя тактов, и использование его промежуточного выхода для инкремента сигнала "count", когда clock_div_int = 1, и когда произошло событие (event, т. е. изменение уровня) сигнала clock_div_int. Заданное здесь условие соответствует положительному перепаду лог. уровня (0 -> 1) сигнала clock_div_int. Область внутри блока architecture и перед началом его ключевого слова begin предназначена для деклараций переменных.
6. Сохраните созданный файл VHDL кликом на иконку дискеты на панели Project Navigator (то же самое можно сделать через меню File -> Save или горячей комбинацией клавиш Ctrl+S).
Теперь мы готовы создать второй модуль. Этот модуль будет еще одним счетчиком, который будет осуществлять шаги через 16 разных последовательностей.
1. Для добавление другого модуля исходного кода снова выберите Project -> New Source... в меню Project Navigator. Выберите VHDL Module, и назовите его "counter". У него будет 5 портов: 4 из них это входы с именами "clock", "reset", "direction" и "pause_design", и один будет 4-битной выходной шиной (Bus) с именем count_out.
Обратите внимание, что надо поставить галочку в столбце Bus для шины count_out, и также поставить в столбце MSB для count_out значение 3 (старший разряд шины) и для LSB значение 0 (младший разряд шины).
2. Кликните Next и затем Finish, будет создан новый файл counter.vhd на языке VHDL.
3. Вернемся к шаблонам Language Templates и найдем счетчик с управлением направлением счета. Этот счетчик находится по следующему пути: VHDL -> Synthesis Constructs -> Coding Examples -> Counters -> Binary -> Up/Down Counters -> /w CE.
4. Скопируйте код из шаблона и вставьте его в файл counter.vhd между строками begin и end блока architecture Behavioral.
5. Теперь нам нужно отредактировать имена сигналов и вставить сигнал сброса reset. Возможно, что Вам покажется полезной функция поиска и замены (меню Edit -> Replace) для выполнения следующих задач:
a. Поменяйте < count_direction > на direction, и удалите угловые скобки вокруг сигналов clock и count. b. Поменяйте < clock_enable > на pause_design. c. Поменяйте полярность для условия активности pause_design:
if pause_design='1'
замените на
if pause_design='0'
d. Добавьте асинхронный сброс reset в код добавлением строки непосредственно после начала оператора process:
if reset='0'then count <="0000";
Событие сброса соответствует '0' потому что кнопка (push button) на демонстрационной плате имеет активный уровень лог. 0 (при нажатии на кнопку она замыкает свой контакт на землю), что соответствует лог. 1 когда кнопка не нажата, и лог. '0', когда кнопка нажата.
6. Поменяйте оператор процесса process (clock) на process (clock, reset, pause_design).
7. Затем нам нужно создать 4-битный сигнал с именем count. Вставьте следующий код между строками с ключевым словом architecture, и ключевым словом begin:
signal count : unsigned (3downto0);
8. В завершение нам нужно подключить сигнал счетчика к порту count_out вставкой следующей строки после строки end process и перед строкой end behavioral:
count_out <=STD_LOGIC_VECTOR(count);
9. Поменяйте оператор if clock, чтобы он начинался с elsif вместо if.
Сейчас мы создали 2 модуля. Конечная функциональная модель будет преобразовывать 4-битное число в 7-битный код для управления 7-сегментным светодиодным индикатором. Для этого создадим еще один модуль.
1. Как обычно, создайте новый модуль VHDL Module через меню Project -> New Source..., назовите модуль display_drive. У этого модуля будет только 2 порта: 4-битный вход с именем count_in и 7-битный выход и именем LED, как показано на рис. 4-11.
Рис. 4-11. Входы и выходы модуля дешифратора для управления 7-сегментным индикатором.
2. Так как этот модуль это чисто логический преобразователь сигнала из одного формата в другой (дешифратор), то в нем не нужен оператор process, здесь будут только операторы присваивания. Вставьте следующий код между строками begin и end блока architecture Behavioral:
with count_in Select
LED <="1111001" when "0001", --1"0100100" when "0010", --2"0110000" when "0011", --3"0011001" when "0100", --4"0010010" when "0101", --5"0000010" when "0110", --6"1111000" when "0111", --7"0000000" when "1000", --8"0010000" when "1001", --9"0001000" when "1010", --A"0000011" when "1011", --b"1000110" when "1100", --C"0100001" when "1101", --d"0000110" when "1110", --E"0001110" when "1111", --F"1000000"whenothers; --0
Модуль в файле display_drive.vhd показан во врезке ниже.
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entitydisplay_driveisPort ( count_in :inSTD_LOGIC_VECTOR (3downto0);
LED :outSTD_LOGIC_VECTOR (6downto0));
enddisplay_drive;
architectureBehavioralofdisplay_driveis
begin
with count_in Select
LED <="1111001" when "0001", --1"0100100" when "0010", --2"0110000" when "0011", --3"0011001" when "0100", --4"0010010" when "0101", --5"0000010" when "0110", --6"1111000" when "0111", --7"0000000" when "1000", --8"0010000" when "1001", --9"0001000" when "1010", --A"0000011" when "1011", --b"1000110" when "1100", --C"0100001" when "1101", --d"0000110" when "1110", --E"0001110" when "1111", --F"1000000"whenothers; --0
endBehavioral;
3. Сохраните файл display_drive.vhd.
[Функциональная симуляция]
Теперь мы можем запустить функциональную симуляцию модуля display_drive. Когда модуль display_drive.vhd подсвечен (выбран) в окне Design -> Hierarhy, окно Process покажет все операции, доступные для этого модуля. Можно синтезировать файл VHDL (synthesis), и затем выполнить его реализацию (implement) в потоке бит (bitstream). Обычно весь дизайн состоит и нескольких модулей низкого уровня (low-level module), подключенных к одному модулю верхнего уровня (top-level module). В этом примере мы выполним симуляцию только модуля низкого уровня, чтобы показать методологию симуляции.
Чтобы симулировать файл VHDL, Вы должны сначала создать testbench - специальный модуль, генерирующий по оси времени входные сигналы для тестируемого модуля.
1. В меню Project снова выберите New Source..., но на этот раз выберите тип модуля VHDL Test Bench, и назовите его display_drive_tb.
2. Нажмите кнопку Next, Вам предложат связать тест с модулем дизайна. Выберите модуль display_drive.
Будет шаблон теста VHDL (модуль display_drive_tb.vhd), котором нужно будет внести правки, чтобы получился тестовый сигнал.
3. В консоли отобразится список ошибок в новом созданном модуле теста display_drive_tb.vhd. Давайте их исправим. Закомментируйте строки, где встречается clock в угловых скобках:
-- constant < clock >_period : time := 10 ns;
-- < clock>_process :process
-- begin-- < clock> <= '0';
-- wait for < clock>_period/2;
-- < clock> <= '1';
-- wait for < clock>_period/2;
-- end process;
-- wait for < clock>_period*10;
Примечание: для комментирования блока текста удобно пользоваться горячей комбинацией клавиш Alt+С. Для этого сначала выделите комментируемый блок, и затем нажмите Alt+C.
Удалите текст между ключевыми словами begin и end блока stim_proc: process.
4. Теперь давайте добавим сигналы изменения входов шины count_in внутрь блока BEGIN/END блока ARCHITECTURE behavior OF display_drive_tb IS.
a. Переименуйте блок stim_proc: process в stim_proc3: process. Это будет процесс для изменения старшего сигнала шины count_in(3).
b. Вставьте внутрь блока stim_proc3: process следующий код:
waitfor200 ns;
count_in(3) <=not count_in(3);
c. Сделайте еще 3 одинаковые копии блоков stim_proc3, и переименуйте их в stim_proc2, stim_proc1 и stim_proc0.
d. Поменяйте в блоках stim_proc2, stim_proc1 и stim_proc0 задержку wait на 100, 50 и 25 нс.
e. Поменяйте в выражении инвертирования сигнала блоков stim_proc2, stim_proc1 и stim_proc0 номера разрядов на 2, 1 и 0 соответственно.
Сохраните полученный модуль display_drive_tb.vhd. Его полный код см. во врезке ниже.
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--USE ieee.numeric_std.ALL;
ENTITYdisplay_drive_tbIS
ENDdisplay_drive_tb;
ARCHITECTUREbehaviorOFdisplay_drive_tbIS-- Component Declaration for the Unit Under Test (UUT)COMPONENTdisplay_drivePORT(
count_in :INstd_logic_vector(3downto0);
LED :OUTstd_logic_vector(6downto0)
);
ENDCOMPONENT;
--Inputssignal count_in :std_logic_vector(3downto0) := (others=>'0');
--Outputssignal LED :std_logic_vector(6downto0);
-- No clocks detected in port list. Replace < clock> below with -- appropriate port name -- constant < clock>_period : time := 10 ns;
BEGIN -- Instantiate the Unit Under Test (UUT)
uut: display_drive PORTMAP (
count_in => count_in,
LED => LED
);
-- Clock process definitions
Примечание: код теста display_drive_tb.vhd виден в дереве проекта Design -> Simulation. Проверить синтаксис редактируемого модуля display_drive_tb.vhd можно двойным кликом на пункт Behavioral Check Syntax.
4. Перейдите снова в дерево симуляции проекта Design -> Simulation. Выберите модуль display_drive_tb, и запустите Xilinx ISE Simulator двойным кликом на Simulate Behavioral Model в окне Process.
5. Откроется окно симулятора ISim, по умолчанию время симуляции будет установлено на 1 мкс. Функциями меню View вы можете управлять просмотром диаграмм входных (шина coint_in[3:0]) и выходных сигналов (шина led[6:0]). View -> In (F8) будет приближать диаграмму (уменьшение масштаба), View -> Out (F7) отдалять диаграмму (увеличение масштаба), View -> To Full View отобразит диаграмму за полное время симуляции.
Треугольник возле имени сигналов шины позволяет развернуть развернуть просмотр отдельных разрядов шины.
Рис. 4-16. Симуляция модели поведения дизайна модуля display_drive.vhd.
[Дизайн VHDL верхнего уровня]
Теперь нам всего лишь осталось создать так называемый модуль верхнего уровня (top level VHDL module), чтобы соединить друг с другом наших 3 логических блока (функции модулей clock_divide, counter и display_drive, чтобы они работали вместе). Сначала мы это сделаем на языке VHDL, а потом то же самое, в целях демонстрации, проделаем с помощью создания схемы.
1. Используйте меню Project -> New Source..., чтобы создать новый модуль типа VHDL Module, и дайте ему имя top. На этом уровне дизайна все порты этого модуля будут ножками нашей микросхемы логики XC2C256. У нас будут 4 входных порта с именами clock_ext, reset_ext, direction_ext и pause_design вместе с одним выходным портом в виде 7-битной шины с именем LED_output.
Примечание: имя top для модуля верхнего уровня выбрано не случайно, это общепринятая негласная практика.
2. Из-за того, что мы будем использовать 3 ранее созданных модуля как компоненты нашего нового модуля top верхнего уровня, то нам просто нужно сначала декларировать их как компоненты, точно так же, как мы это делали в модуле делителя частоты clock_divide. Между начальной строкой aarchitecture Behavioral модуля top и строкой с оператором begin вставьте 3 декларации компонентов следующим образом:
componentdisplay_drivePort ( count_in :inSTD_LOGIC_VECTOR (3downto0);
LED :outSTD_LOGIC_VECTOR (6downto0));
endcomponent;
begin
...
Обратите внимание, что порты этих трех компонентов точно соответствуют портам модулей, которые мы создали ранее (clock_divide, counter и display_drive).
3. Когда компоненты декларированы, мы должны использовать в дизайне экземпляры этих компонентов (instances). Введите следующий текст в коде модуля top после оператора begin и перед оператором end Behavioral:
U3: display_drive
Portmap (count_in => count_in_sig,
LED => LED_output);
endBehavioral;
Обратите внимание, что все порты подключаются либо к декларации entity модуля top (внешние сигналы clock_ext, reset_ext, direction_ext, LED_output) либо к промежуточным сигналам (clock_div_sig, count_in_sig).
При этом вид отображения модулей в окне дерева дизайна Design -> Implementation также поменяется. Раньше модули были показаны в виде простого списка, а теперь отражается тот факт, что модуль top является главным, т. е. "модулем верхнего уровня", а модули clock_divide, counter и display_drive используются как подчиненные, для определения экземпляров объектов U1, U2 и U3 соответственно.
4. Теперь нам нужно декларировать 2 промежуточных сигнала, которые используются для обмена данными между модулями. После последней декларации компонента и перед оператором begin, введите две декларации сигналов:
signal count_in_sig :std_logic_vector (3downto0);
signal clock_div_sig :std_logic;
5. Сохраните полученный модуль top.vhd, его полный код см. во врезке ниже.
U3: display_drive
Portmap (count_in => count_in_sig,
LED => LED_output);
endBehavioral;
[Создание модуля верхнего уровня на базе схемы]
Программа графического редактора схемы (ECS schematic capture) также позволяет создавать функциональные модули, как мы это делали ранее на языке VHDL. Также можно разработать и модуль верхнего уровня, соединяющий друг с другом низкоуровневые модули. Графический редактор ECS разработан по принципу визуального манипулирования логическими устройствами по принципу "что видите, то и получаете". Обычно большинство приложений Windows построены именно по такому принципу, позволяя пользователю работать с выбираемыми объектами. Возможно, что для инженеров, у которых больше опыта работы со схемами, чем опыта с программированием, редактор ECS позволит быстрее начать синтезировать логические устройства.
Создание модуля верхнего уровня. Перед тем, как можно создать будет создать схему верхнего уровня, нам сначала понадобится создать символы для 3 модулей VHDL clock_divide, counter и display_drive. Это добавит схематическое представление каждого модуля к схематической библиотеке проекта.
1. Выберите модуль clock_divide.vhd в окне Design -> Implementation, и разверните раздел Design Utilities в окне Process. Сделайте двойной клик на пункте Create Schematic Symbol. Повторите это действие для файлов counter.vhd и display_drive.vhd.
2. Теперь создадим лист схемы. Выберите в меню Project -> New Source..., тип модуля установите в Schematic, и дайте ему имя top_sch, как показано на рис. 4-21.
Рис. 4-21. Создание нового модуля top_sch на основе схемы.
Кликните Next, затем Finish. Откроется окно редактора ECS Schematic Editor. При этом фокус автоматически перескочит на закладку Options.
3. Библиотека символов (symbol libraries) доступна на закладке Symbol (она слева от закладки Options). В верхней части окна Вы увидите раздел библиотек, содержащий путь до папки, где находится Ваш проект. Если Вы кликните на эту категорию библиотек, то увидите 3 символа, перечисленные ниже в отдельном списке. Это те 3 символа, которые мы ранее создали, см. рис. 4-22.
4. Кликните на символ clock_divide, и переместите курсор на лист схемы. Курсор изменится на жирный крест, справа от которого будет графика выбранного символа clock_divide. Поместите символ в левой части листа схемы, примерно посередине между верхним и нижним краем листа.
5. Затем кликните на символе counter, и поместите его на листе схемы справа от символа clock_divide, через небольшой интервал между ними.
6. В завершение кликните на символе display_drive, и поместите его справа от символа counter. Ваша схема должна принять примерно такой вид:
Рис. 4-23. Лист схемы в редакторе ECS.
Соединение блоков друг с другом
7. Соединим блоки схемы друг с другом сигнальными линиями. Для этого служит инструмент Add Wire. Вот так выглядит соответствующая кнопка на панели инструментов редактора ECS:
Рис. 4-24. Инструмент Add Wire.
8. Кликните на выход clk_div символа clock_divide, переместите курсор вправо и сделайте клик на входе clock символа counter. Отобразится проводник между двумя этими портами.
9. Повторите то же самое, соединяя друг с другом выход count_out(3:0) символа counter и вход count_in(3:0) символа display_drive. Обратите внимание, что это 4-битная шина, поэтому линия соединения будет толще.
10. Теперь, пока у нас активен режим инструмента Add Wire, добавим еще проводники к входным и выходным портам, чтобы потом их можно было сделать ножками ввода/вывода (I/O pins). Сначала кликните на порт clock_osc символа clock_divide, и нарисуйте короткий проводник от него в сторону левого края схемы. Заканчивать проводник, если он не приходится на вывод компонента, следует двойным щелчком мыши. Повторите то же самое со входами reset, direction и pause_design символа counter, выравнивая левые стороны проводников. Затем нарисуйте еще короткий проводник от выхода LED(6:0) в сторону правого края схемы.
Получившаяся схема должна выглядеть примерно так:
Рис. 4-25. Блоки соединены на схеме друг с другом.
Назначение имен цепей
11. Дадим имена удобочитаемые имена цепям сигналов. По умолчанию они имеют автоматически назначенные имена наподобие XLXN_1, XLXN_2(3:0) и т. п. Для этого имеется инструмент Add Net Name и соответствующая кнопка на тулбаре:
Кликните на кнопку инструмента Add Net Name. Слева отобразится диалог опций "Add Net Name Options". В поле ввода "Name:" этого диалога введите clock_ext, и затем сделайте двойной клик на конце проводника, который Вы провели от входа clock_osc символа clock_divide. Затем введите reset_ext, и сделайте двойной клик на конце цепи порта reset. Введите direction_ext, и сделайте двойной клик на конце цепи порта direction. Введите pause_design, и сделайте двойной клик на конце цепи порта pause_design.
12. В завершение введите LED_output(6:0) и сделайте двойной щелчок на конце шины выхода символа display_drive.
Маркеры I/O
13. Осталось добавить маркеры на входы и выходы. Для этого служит инструмент Add I/O Marker и соответствующая кнопка на тулбаре:
Выберите этот инструмент, и удерживая левую кнопку мыши, очертите прямоугольник вокруг имен цепей, назначенных на шагах 11 и 12. Направление порта будет выбрано автоматически, и схема примет следующий вид:
Рис. 4-26. Схема с добавленными маркерами входов и выходов.
Сохраните дизайн (File -> Save, или выполните Ctrl+S) и закройте закладку Schematic Editor. Обратите внимание, что ISE автоматически распознает файл схемы как файл верхнего уровня, и окно Design -> Hierarchy отобразит дерево модулей соответствующим образом. Если выбрать файл top_sch, то в окне Processes -> Design Utilites двойной клик на пункте View HDL Functional Model запустит автоматическую генерацию текста на языке VHDL (файл top_sch.vhf), функционально аналогичного тому, что мы создавали вручную ранее в модуле top.vhd. Инструмент синтеза будет так же обрабатывать файл точно так же, как и любой другой модуль, написанный на языке HDL или Verilog вручную.