Практические вопросы проектирования устройств с применением ПЛИС Spartan–6
Введение
При практическом проектировании устройств, в которых предполагается использование ПЛИС Spartan‑6, необходимо организовать ее питание, загрузку конфигурации и подключить выводы, имеющие специальное или двойное назначение. Эти вопросы подробно освещены в документации [1, 2, 3], однако для разработчиков, находящихся на этапе выбора элементной базы для нового проекта, желательно иметь сжатую, но при этом исчерпывающую информацию о конкретных действиях, которые они должны произвести с прежде не использованной микросхемой. В практике многих инженеров наверняка встречались конструкции, требовавшие доработки из-за пропущенного pull-up-резистора или несоблюдения правил включения микросхемы в нужном режиме. В данной статье описаны основные вопросы, касающиеся обязательных соединений для Spartan‑6, позволяющих разработчикам оценить, какие дополнительные компоненты понадобятся им для проекта, как ПЛИС дополнительно нагрузит подсистему питания и т. п. Речь пойдет в первую очередь о двух представителях семейства Spartan‑6 — XC6SLX4 и XC6SLX9, которые выпускаются в планарных корпусах TQFP144. Остальные актуальные на сегодня FPGA Xilinx существуют только в корпусах BGA, что заставляет искать соответствующее оборудование для монтажа.
Питание
FPGA Spartan‑6 имеют три линии питания: для ядра (Vcore), периферийных (Vio) и вспомогательных (Vaux) устройств. Две последние могут быть объединены, таким образом, для проекта будет достаточно источника 1,2 для ядра и 3,3 В для периферии. Питание Vaux может быть выбрано в диапазоне 2,5–3,3 В, а потому понадобится отдельный источник, если питание периферии по каким-то причинам установлено ниже этого диапазона. Напряжение Vio может быть подано в диапазоне 1,2–3,3 В.
Величина потребляемого тока зависит от загруженного проекта и нагрузки, подключенной к выходам ПЛИС. Потребление ядра (линия 1,2 В) определяется в основном динамической составляющей, оно пропорционально тактовой частоте и количеству использованных ресурсов ПЛИС. Точное значение определяется только экспериментально, однако можно указать характерные величины токов для типичных применений. Для микросхем LX4 и LX9, о которых идет речь в публикации, типичное потребление ядра составляет чуть меньше 100 мА. Уточненное значение потребляемого тока можно определить с помощью утилиты XPower, имеющейся в составе САПР ISE.
Потребление периферийных модулей (линия Vio) зависит от нагрузки, подключенной к ПЛИС. Максимальный ток, допустимый для одного выхода, равен 12 мА, что можно использовать для оценки верхней границы потребления. В то же время не следует рассчитывать на нормальную работу ПЛИС, у которой все 102 вывода функционируют в таком режиме.
Питание ПЛИС проще всего обеспечить с помощью интегрального трехвыводного стабилизатора, например LM117. Такие стабилизаторы выпускаются многими производителями и имеют варианты как с фиксированным выходным напряжением (в том числе 3,3 В), так и с регулируемым (adjustable). Интересно, что регулируемые стабилизаторы могут быть использованы для получения напряжения ядра (1,2 В) без дополнительных компонентов, поскольку, если вход регулирования подключить к «земле», стабилизатор будет выдавать опорное напряжение, равное 1,23–1,27 В. Для ПЛИС это находится в пределах официально допустимого 10%-го допуска.
Многие интегральные стабилизаторы самовозбуждаются при малом потреблении тока, поэтому желательно организовать небольшую балластную нагрузку. Также можно рекомендовать включить конденсатор небольшой емкости (10–100 нФ) между входом и выходом.
Для любой системы питания важно обеспечить фильтрацию помех. Кроме электролитических конденсаторов большой емкости, служащих для подавления низкочастотных колебаний большой амплитуды, требуется и установка конденсаторов типа NPO или X7R для фильтрации высокочастотных помех. Печатная дорожка от вывода ПЛИС до конденсатора имеет индуктивность, которой для обычных применений пренебрегают, но при попытке фильтрации высокочастотных помех она способна снизить эффективность конденсатора. Поэтому такие конденсаторы необходимо размещать в непосредственной близости от выводов питания, соединяя их с ПЛИС кратчайшим путем. Ориентировочной длиной следует считать 5 мм, хотя при трассировке платы может возникнуть необходимость идти на компромиссы. В целом рекомендуется установить 4–6 конденсаторов на выводы питания ядра и по 2–3 конденсатора на каждый банк питания (на каждую сторону корпуса TQ144).
Отдельным вопросом является применение импульсных источников питания. Они имеют более высокий КПД, однако добавляют высокочастотную составляющую помех на частоте внутреннего преобразователя. Обычно потребность в импульсных стабилизаторах связана с высокими токами нагрузки, но для ПЛИС начального уровня это не нужно. Тем не менее не существует принципиальных препятствий для использования импульсных стабилизаторов напряжения.
Сопряжение ПЛИС с другими микросхемами
Обычно ПЛИС используют питание интерфейсов ввода/вывода 3,3 В. В связи с этим часто задают вопрос, каким образом следует подключать ПЛИС к микросхемам с питанием 5 В? В целом можно ответить, что ПЛИС способны работать совместно с 5‑вольтовыми микросхемами, но с учетом некоторых ограничений.
Рассмотрим две ситуации.
- ПЛИС читает данные с микросхемы, питающейся от 5 В
В этом случае возникает вопрос, не будет ли повреждена ПЛИС при подаче на нее напряжения с номиналом большим, чем ее напряжение питания. Простейшей и официально рекомендованной схемой сопряжения является обычный токоограничивающий резистор, включенный последовательно. Резистор подбирают таким образом, чтобы ограничивать ток величиной не более 10 мА. Резистор номиналом 180 Ом допускает подачу на вход напряжения 5,1 В.
Следует обратить внимание, что микросхемы с 5‑вольтовым питанием и выходом ТТЛ в действительности не выдают на выходе 5 В для состояния логической единицы. Напряжение холостого хода для различных серий ТТЛ составляет от 3 до 3,5 В, что безопасно для ПЛИС. Однако применение резистора в 180 Ом может быть рекомендовано для всех входов, сопрягаемых с 5‑вольтовым окружением.
Внутри ПЛИС в блоках ввода/вывода установлены защитные диоды, соединенные с линией питания ввода/вывода. Поэтому формальных ограничений на входное напряжение не существует до тех пор, пока внешний резистор ограничивает ток на уровне 10 мА.
- Выход ПЛИС подключен к входу микросхемы, питающейся от 5 В
В данном случае возможность прямого подключения зависит от типа входа внешней микросхемы. Для входа ТТЛ с фиксированным порогом логической единицы возможно надежное чтение выхода ПЛИС без дополнительных компонентов. Напряжение холостого хода, замеряемое на выходе ПЛИС, обычно составляет 3–3,05 В (для сравнения: порог срабатывания микросхем ТТЛ составляет 2,4 В).
Проблема может возникнуть при подключении к 5‑вольтовой микросхеме, входы которой имеют уровни КМОП. При питании 5 В порог срабатывания может быть равен 4 или 4,5 В, и чтение выхода ПЛИС становится ненадежным. В этом (и только в этом) случае требуется преобразователь уровня. Например, специальная микросхема level shifter (рис. 1) или буферный элемент с 5‑вольтовым питанием и входами типа ТТЛ (в частности, 74hct244, но не 74hc244). На рис. 2 показана принципиальная электрическая схема буферного элемента 74hct244.
На рис. 3 представлена сводная схема подключения FPGA к внешним микросхемам различных типов. Здесь видны схемы сопряжения, используемые в описанных выше случаях. Отдельно рекомендуется отказаться от попыток прямого управления мощными полевыми транзисторами (например, встречаются экземпляры устройств с вышедшими из строя MOSFET), поскольку на практике обычно недостаточно выходного напряжения FPGA для его перевода в режим насыщения. В результате сопротивление сток-исток для MOSFET не достигает минимальной величины, приводимой в его документации, хотя переключающий режим формально имеет место. При этом повышенное сопротивление сток-исток означает увеличение рассеиваемой мощности с преждевременным выходом MOSFET из строя. В данном случае правильным будет использование транзисторного ключа с интегрированным преобразователем, управляемым ТТЛ-уровнями, или применение дополнительного управляющего биполярного транзистора.
Загрузка конфигурации
ПЛИС относится к устройствам со статической памятью. Это означает, что каждый раз после включения питания следует загрузить конфигурацию из внешнего энергонезависимого источника. Семейство Spartan‑6 поддерживает несколько видов внешней памяти и имеет дополнительный интерфейс JTAG.
Для хранения одной конфигурации ПЛИС Spartan‑6 LX4 и LX9 достаточно устройства памяти емкостью 4 Мбит (точные значения: 2 731 488 и 2 742 528 бит соответственно). Дополнительно конфигурационный поток может быть сжат (применением соответствующей настройки в САПР), однако степень сжатия существенно зависит от коэффициента использования ПЛИС. Минимальный объем конфигурационного потока для проекта, состоящего из одного провода, соединяющего два вывода ПЛИС, составляет приблизительно 0,9 Мбит. Это ни в коей мере не означает, что память размером 1 или 2 Мбит может быть заложена в проект на ранних стадиях разработки.
Интерфейс для загрузки конфигурации имеет следующие выводы:
- CCLK — тактовый сигнал; в режиме Master является выходом, а в режиме Slave — входом;
- DIN — вход конфигурационных данных;
- PROGRAM — вход сброса, активный уровень низкий, служит для запуска процесса конфигурирования;
- INIT — двунаправленный вывод с активным низким уровнем, служащий для задержки загрузки данных (если извне подан уровень логического нуля) или сигнализирующий об ошибке контрольной суммы;
- DONE — выход готовности FPGA, принимает уровень логической единицы при успешном завершении загрузки; требует внешнего резистора (уровень нуля, поданный внешней микросхемой, задержит старт FPGA);
- DOUT — выход данных, конфигурационные данные с DIN появляются на этом выходе после завершения загрузки конфигурации; служит для формирования последовательных цепочек FPGA, где выход DOUT подключается к входу DIN следующей FPGA;
- M0, M1 — входы выбора режима конфигурирования; обычно к ним подключаются pull-up-резисторы и джамперы, замыкающие эти входы на «землю», что позволяет установить любой режим конфигурирования.
В итоге можно использовать следующие технические решения:
- Флэш-память серии XCF производства Xilinx.
- Эта память специально спроектирована для загрузки FPGA Xilinx. Она имеет интерфейс JTAG в дополнение к интерфейсу с FPGA и может быть подключена к FPGA с помощью минимального количества дополнительных компонентов (резисторов). Для микросхем LX4 и LX9 достаточно применения флэш-памяти XCF04S. Схема ее включения показана на рис. 4.
- Флэш-память с интерфейсом SPI.
- Память такого типа обычно существенно дешевле, чем специализированные микросхемы семейства XCF. Подключение SPI-флэш к FPGA показано на рис. 5.
При подсоединении программатора наличие внешней памяти может быть автоматически определено. В этом случае будет предложено выполнить и программирование флэш-памяти. В настоящее время программатором Impact поддерживаются следующие семейства флэш-памяти:
- Atmel AT45DB;
- Nymonix M25P, M25PE, M45PE;
- Winbond W25Q.
Сами FPGA не проверяют код микросхемы памяти при загрузке конфигурации. Например, успешно работают флэш-ПЗУ семейства SST25V, однако для всех микросхем, официально не поддерживаемых утилитой Impact, необходимо позаботиться о способе их программирования. Так, через JTAG может быть загружена конфигурация, обеспечивающая доступ к выводам, подключенным к флэш-памяти, а конфигурационный поток будет передан с помощью того же JTAG или пользовательского интерфейса (USB, Ethernet и т. д.).
Следует обратить внимание, что выход FPGA DOUT подключен не к входу флэш-памяти DIN, а служит для образования цепочки из нескольких FPGA, чтобы загружать их из одной микросхемы. Тем не менее управление входом DIN требуется, чтобы управлять работой флэш-памяти. Для этого используется выход MOSI (Master Out, Slave In).
Кроме интерфейса, специально предназначенного для загрузки конфигурации, ПЛИС имеют интерфейс JTAG. Он использует выделенные линии TMS, TCK, TDI, TDO. Интерфейс предназначен прежде всего для отладки, но применяется и для загрузки конфигурации. JTAG доступен в любом режиме, независимо от установленных уровней на M0, M1. Сигналы TMS и TCK подаются на все микросхемы с интерфейсом JTAG, установленные на плате, а сигналы TDI (вход данных) и TDO (выход данных) образуют цепочку, где выход TDO подключен к входу TDI следующей микросхемы. Если на плате только одна микросхема имеет интерфейс JTAG, ее сигналы TDI и TDO подключаются к одноименным выводам разъема. Внешние токоограничивающие резисторы для этого интерфейса не требуются, однако можно предусмотреть резисторы, согласующие длинную линию. На практике JTAG не является чрезмерно требовательным к длине или форме трассировочных линий. Это не означает, будто на них можно не обращать внимания, но и нет необходимости размещать разъем JTAG на минимальном расстоянии от FPGA.
Программатор, выпускаемый Xilinx (рис. 6), удобен в первую очередь тем, что позволяет использовать все возможности программирования и отладки, предлагаемые САПР Xilinx. При его наличии проектирование становится в полной мере сквозным, завершаясь непосредственно запуском полученной в САПР конфигурации на микросхеме, подключенной к программатору. Однако относительно высокая цена делает такой программатор не слишком подходящим приобретением для быстрого старта.
Альтернативными вариантами могут быть:
- Использование связки МК+ПЛИС, в которой микроконтроллер подключен к конфигурационному интерфейсу ПЛИС и имеет скоростной интерфейс (USB или Ethernet), позволяющий передать с ПК полученную в САПР конфигурацию и загрузить ее в ПЛИС по конфигурационному интерфейсу. В этом случае МК полезен тем, что добавляет к проекту свои периферийные устройства, однако для передачи конфигурационного файла в такую систему необходимо разработать отдельные утилиты.
Протокол USB предусматривает передачу пакетов данных со скоростью не более 1000 пакетов в секунду. Достигать высоких скоростей передачи данных можно только в том случае, если удается обеспечить соответствующее наполнение этих пакетов. Некоторые микросхемы преобразователей USB допускают независимое управление выводами (например, так называемый режим bit bang), что может навести на мысль об использовании подобного режима для загрузки конфигурации. Однако в данном случае каждый пакет будет однократно переключать состояние выводов, а не формировать последовательность, к тому же программное управление линией CCLK потребует двух посылок. Поэтому скорость загрузки конфигурации окажется равной 500 бит/с, что крайне мало для нормальной работы с ПЛИС. Вот почему при использовании МК необходимо убедиться, что реальная скорость передачи пользовательских данных и воспроизведение протокола загрузки конфигурации будут происходить с приемлемой скоростью.
- Модули программатора сторонних производителей.
Некоторые компании выпускают готовые модули с интерфейсом JTAG, специально созданные для работы с ПЛИС Xilinx. На рис. 7 показан модуль USB-JTAG производства Digilent.
Источники тактовых сигналов
У FPGA нет внутри высококачественного источника тактового сигнала. Среди аппаратных примитивов есть генератор, используемый в Master-режимах загрузки конфигурации (когда FPGA является источником тактового сигнала для внешней флэш-памяти), однако он имеет большой разброс номинального значения частоты между отдельными микросхемами. Рекомендуется использовать внешний кварцевый генератор (рис. 8), подключаемый к входу, помеченному как GCLK (Global Clock).
Отдельным вопросом является повторение схемы с внешним кварцевым резонатором (не интегральным генератором). Если широко известная схема на дискретных логических компонентах выглядит, как показано на рис. 8, очевидным желанием может быть ее повторение на базе FPGA, где в качестве инверторов выступали бы программируемые ячейки ПЛИС. Формально данная схема имеет право на существование, однако на практике ее параметры нестабильны. Стоимость интегрального генератора несущественно превышает стоимость отдельного кварцевого резонатора, но для резонатора можно подобрать такое сочетание параметров ПЛИС и взаимного размещения ячеек, реализующих инверторы генератора, что надежный запуск этой схемы окажется под вопросом. Здесь можно отметить, что эксперименты с реализацией генератора на базе FPGA не являются доказательством надежной работы такой схемы во всем диапазоне допустимых условий эксплуатации и, что особенно актуально для одиночных экспериментов, при серийном изготовлении изделий. Поэтому, если нет острой необходимости, не следует экономить на данном компоненте проекта.
Тактовые генераторы внутри FPGA имеют собственный диапазон допустимых входных частот. Для Spartan‑6 он составляет 5–350 МГц. Это означает, что, например, популярная частота 4 МГц не может быть использована для DCM (что подтверждается экспериментально). Однако сами DCM могут сформировать эту частоту из внешнего тактового сигнала.
При подключении генератора с высокой (свыше 100 МГц) частотой рекомендуется использовать дифференциальный интерфейс. Для этого необходим специальный выход генератора в виде дифференциальной пары, подключаемой к GCLK_P- и GCLK_N-входам FPGA. Входы не могут быть выбраны произвольно среди всех P и N тактовых входов, а должны образовывать дифференциальную пару на кристалле. Ввод дифференциального сигнала в проект при этом выполняется с помощью специального буфера IBUFGDS (входной глобальный тактовый буфер с дифференциальным входом).
Настройка генераторов тактовых сигналов
Компоненты DCM и PLL имеют довольно много сигналов, и их применение в проекте требует определенного внимания. В то же время для формирования внутреннего тактового сигнала настоятельно рекомендуется использовать именно такую схему. Для упрощения настройки DCM и PLL можно воспользоваться инструментом Clocking Wizard, интерфейс которого показан на рис. 9.
Результат работы данного мастера — сгенерированное IP-ядро с настроенным формирователем тактового сигнала. Также создается шаблон для его использования в проекте в структурном стиле. Его пример приведен ниже. Курсивом выделены сигналы, которые должны быть введены пользователем.
clock_generator : clock port map (-- Clock in ports CLK_IN1 => CLK_IN, -- Clock out ports CLK_OUT1 => clk, CLK_OUT2 => clk_2);
Формирование выходного тактового сигнала
Семейство Spartan‑6 имеет некоторые ограничения по трассировке внутренних цепей. Они не являются критичными, но не позволяют напрямую вывести тактовый сигнал на внешний вывод микросхемы. Вместо этого необходимо использовать прием, именуемый clock forwarding. Тактовый сигнал действительно нельзя подать непосредственно на выход ПЛИС, однако его можно подать на тактовый вход триггера ODDR, находящегося непосредственно в нужном блоке ввода/вывода. Этот триггер не может быть автоматически применен синтезатором и требует установки в структурном стиле, как показано в примере ниже. В этом примере жирным шрифтом выделены строки, сигналы в которых требуют заполнения разработчиком. На рис. 10 показано технологическое представление синтезированной схемы.
ODDR2_clka_inst: ODDR2 generic map ( DDR_ALIGNMENT => "NONE", — Sets output alignment to "NONE", "C0", "C1" INIT => '0', — Sets initial state of the Q output to '0' or '1' SRTYPE => "SYNC") — Specifies "SYNC" or "ASYNC" set/reset port map ( Q => gen_clk, — 1‑bit output data C0 => clk, — 1‑bit clock input C1 => not (clk), — 1‑bit clock input CE => clk_en, — 1‑bit clock enable input D0 => '1', — 1‑bit data input (associated with C0) D1 => '0', — 1‑bit data input (associated with C1) R => '0', — 1‑bit reset input S => '0' — 1‑bit set input );
Схема работает следующим образом. Триггер ODDR имеет два входа данных — D0 и D1, связанных с тактовыми входами C0 и C1 соответственно. В примере видно, что на D0 подана логическая единица, а на D1 — логический ноль. Поэтому по фронту тактового сигнала clk, который также подан на C0, триггер запишет логическую единицу (с D0), а по спаду clk, который после инвертирования окажется фронтом для C1, будет записан логический ноль с D1. Временные диаграммы работы такой схемы изображены на рис. 11. Таким образом, на выходе окажется не сам тактовый сигнал, а данные, которые будут меняться точно так же. Этот прием может быть применен и для других семейств ПЛИС Xilinx, однако для Spartan‑6 он является обязательным.
Захват данных с внешних линий
Прием данных с внешней шины, тактируемой отдельным сигналом, может вызвать определенные сложности. Очевидным, но некорректным решением является подача внешнего тактового сигнала на выделенный тактовый вход GCLK и захват данных по фронту этого сигнала. Такая схема формально корректна для идеальных временных характеристик, однако вызывает появление метастабильных состояний.
Под метастабильным состоянием понимается такой режим работы триггера, в котором его выход имеет промежуточный уровень напряжения, воспринимаемый разными компонентами как логический ноль или логическая единица (рис. 12). Это нежелательный режим, в котором триггеры оказываются вынужденно, если на входе данных напряжение изменяется непосредственно перед приходом фронта тактового сигнала. По спецификации каждый триггер имеет время установки (setup time) и время удержания (hold time) — интервалы времени до и после фронта тактового сигнала, в течение которых уровень сигнала на его входе D изменяться не должен. Метастабильность носит вероятностный характер и объясняется особенностями переключения транзисторов, из которых состоит триггер, а не какими-либо специальными приемами проектирования для цифровой электроники. Метастабильным может стать сигнал, вводимый в ПЛИС, скажем, от механического переключателя или любой внешней микросхемы, которая тактируется не от внутреннего источника ПЛИС.
Любая конструкция, использующая два тактовых сигнала, потенциально подвержена метастабильности, которую следует устранить или хотя бы снизить вероятность ее появления. Даже в случае, когда номинальные значения тактовых частот одинаковы или кратны, нормальная работа возможна лишь в недостижимом на практике идеальном случае — если фронты обоих тактовых сигналов появляются в строго определенные моменты времени. Именно эту ситуацию и увидит разработчик, попытавшийся промоделировать поведение подобной схемы. Это связано с тем, что идеальная модель (с фиксированным периодом тактового сигнала), очевидно, покажет и идеальное поведение схемы. Однако каждый генератор имеет не только свое номинальное значение частоты, но и собственный температурный и долговременный дрейф, собственное распределение помех, что вызовет как случайные колебания периода вокруг некоторого среднего значения, так и систематический дрейф этой средней величины. Например, два кварцевых генератора с номинальным значением частоты 100 МГц, различающиеся на 30 ppm (типичное значение нестабильности для генераторов), будут иметь разницу в частотах, равную 3000 Гц! Соответственно, каждую секунду один из генераторов может формировать на 3000 периодов больше другого, и интервал времени между приходом фронтов тактового сигнала с двух генераторов за это время будет принимать значения от 0 до полного периода тактового сигнала. Вероятность попадания в метастабильное состояние при этом, очевидно, ненулевая.
Простейшей схемой, снижающей вероятность попадания в метастабильное состояние, является узел, показанный на рис. 13.
В схеме на рис. 13 решение о том, в каком именно состоянии оказался триггер signal_meta_reg, всецело отдано второму триггеру, signal_out_reg. В данном случае худшее, что может произойти, — переход в нужное состояние на такт позже. С точки зрения схемотехники, это приемлемая цена решения вопроса. Альтернативой могла бы стать ситуация, когда signal_meta читался бы двумя триггерами, которые восприняли бы его противоположным образом. В итоге один и тот же сигнал в разных частях схемы иногда представлялся бы и логическим нулем, и логической единицей. Цель защиты от метастабильности — устранение именно такой неопределенности, а не чтение какого-то «истинного» состояния линии. Иными словами, разработчику следует быть готовым к поведению схемы, показанной на рис. 13, и не ожидать немедленной реакции на изменение входного сигнала.
Чуть большую сложность имеет схема на базе FIFO. В этой схеме приемник ориентируется на флаг «FIFO пуст», при пропадании которого можно читать данные. Для большей безопасности можно контролировать глубину FIFO и читать данные лишь в том случае, если в FIFO уже записано как минимум 2 числа (факт начала записи второго числа гарантирует, что предыдущая запись уже завершилась).
FIFO может быть собрано на базе распределенной памяти, а для ответственных случаев — и на базе блочной. Однако блочная память является дефицитным ресурсом для Spartan‑6, особенно у младших микросхем, поэтому возможность использования такого блока должна быть спланирована заранее. На рис. 14 показана схема ввода сигнала с помощью FIFO.
Если тактовая частота внешнего сигнала невысока (на практике не превышает 20–50 МГц), удобно использовать схему bus capturing. Она показана на рис. 15 на примере захватов сигнала интерфейса SPI. В ней тактовый сигнал подается не на тактовый вход, а на вход данных триггера, который тактируется глобальным тактовым сигналом. Если говорить точнее, это должен быть тот же тактовый сигнал, поданный на приемные устройства для данных, или же сигнал, кратный ему по частоте и сформированный тем же внутренним тактовым генератором (DCM или PLL). Частота такого сигнала должна быть не менее чем в 2 раза выше внешней тактовой частоты.
На рис. 15 видно, что несколько триггеров образуют линию задержки, хранящую несколько последовательных «снимков» состояния внешней тактовой линии. Если на линии имел место фронт тактового сигнала, то после его прихода начнется последовательное переключение триггеров цепочки в логическую единицу. Это переключение будет синхронным с внутренним тактовым сигналом, а потому метастабильность в такой схеме не возникнет. Комбинация 1 на триггере DD2 и 0 на DD3 означает, что по линии clk_external пришел фронт тактового сигнала. Соответственно, на следующем такте нужно произвести захват данных по линии data_external. Цепочка триггеров на линии data задерживает данные таким образом, чтобы в момент распознавания фронта было записано не текущее состояние data_external, а то, которое имело место в момент прихода фронта тактового сигнала на вход ПЛИС. При необходимости подстройки момента захвата данных эту цепочку можно сделать длиннее или короче.
Ниже приведен фрагмент модуля на VHDL, осуществляющего прием данных с интерфейса SPI.
sclk_0_pipe <= sclk when rising_edge(clk); sclk_1_pipe <= sclk_0_pipe when rising_edge(clk); mosi_0_pipe <= mosi when rising_edge(clk); mosi_1_pipe <= mosi_0_pipe when rising_edge(clk); spi_cs_0_pipe <= spi_cs when rising_edge(clk); spi_cs_1_pipe <= spi_cs_0_pipe when rising_edge(clk); process(clk) begin if rising_edge(clk) then if spi_cs = '1' then spi_state <= 0; elsif sclk_0_pipe = '0' and sclk_1_pipe = '1' and spi_cs_1_pipe = '0' then spi_reg(spi_state) <= mosi_1_pipe; miso <= spi_tx_reg(spi_state); spi_state <= spi_state + 1; end if; end if; end process;
В приведенном фрагменте входные сигналы интерфейса SPI (sclk, miso, spi_cs) подаются на цепочку из двух конвейеризующих триггеров. Фронт тактового сигнала sclk распознается по условию sclk_0_pipe = ‘0’ and sclk_1_pipe = ‘1’, что при активном сигнале cs (для SPI активным уровнем является логический ноль) вызывает загрузку очередного бита с линии mosi (Master Out, Slave In) в очередной разряд регистра, хранящего данные, принятые по SPI. Регистр spi_state применяется в качестве счетчика (индекса) принятых битов.
Заключение
Приведенные в статье сведения позволят разработчикам электронных устройств добавить к своим проектам ПЛИС начального уровня, предусмотрев подключение всех обязательных для ее работы компонентов. Настоятельно рекомендуется подключение и настройка формирователя тактового сигнала, а также соблюдение правил синхронного проектирования и использование приведенных примеров ввода в кристалл асинхронных внешних сигналов.