При разработке цифровых устройств нередко возникает необходимость разделять функциональные блоки на группы, использующие синхросигналы с разными параметрами (т.н. домены синхронизации – Clock Domain). Основными параметрами любого синхросигнала является тактовая частота и соответствующий ей период. Также для ряда элементов, узлов и блоков имеет значение скважность синхросигнала, определяющая длительность низкого и высокого уровней в течение периода, и нестабильность периода – параметр «Jitter».
Несмотря на наличие в устройстве синхросигналов с различными параметрами, в большинстве случаев для генерации этих сигналов используется единый источник, — внешний генератор, формирующий опорную частоту. В конкретных проектах возможно применение нескольких генераторов, формирующих некратные опорные частоты, например частоту 48МГц для контроллера USB, частоту 3.6864МГц для каналов UART и частоту 100МГц для процессорных ядер, памяти SDRAM и контроллера сети Ethernet. Необходимые для нормального функционирования функциональных блоков СБИС или ПЛИС синхросигналы формируются из опорных сигналов путём умножения и деления частоты. Функцию умножения частоты в ПЛИС архитектуры FPGA реализуют узлы ФАПЧ (DLL, PLL, блоки DCM и CMT). Применение данных ресурсов кристалла детально описано производителями в соответствующей документации [3,4].
В отличие от умножителей частот, делители частоты могут быть построены на логических ресурсах общего назначения, основу которых составляют регистры и генераторы комбинационных схем. Следует отметить, что применение логических ресурсов для формирования синхросигнала допускается средствами САПР и архитектурой большинства ПЛИС, но крайне не рекомендуется производителями вследствие вероятности появления ложных переходов и выбросов в полученном синхросигнале, вызванных переключением комбинационных схем. Таким образом, в ПЛИС с архитектурой FPGA для формирования синхросигналов предпочтительно использовать имеющуюся инфраструктуру, включающую специализированные ресурсы кристалла: блоки ввода синхросигнала, соединённые с определёнными выводами корпуса; блоки DLL, PLL, DCM или CMT; глобальные сети синхронизации, транслирующие синхросигнал в объёме кристалла с наименьшими искажениями.
Возможны два случая синхронизации функциональных блоков и узлов на пониженной частоте, полученной путём деления опорной частоты:
1. частота синхронизации кратна опорной частоте,
2. частота синхронизации получена путём деления опорной частоты на дробный коэффициент.
В первом случае крайне желательно использовать принцип разрешения синхронизации, заключающийся в применении триггеров и регистров с входом CE (Clock-Enable). Организация элементарного триггера с входом CE представлена на рис. 1. За основу взят триггер D-типа с синхронизацией по фронту и асинхронной установкой начального значения – RST. Вход CE реализует принцип разрешения синхронизации путём коммутации через мультиплексор MX-2:1 внутреннего информационного входа триггера либо на внешний источник данных — в случае CE = «1», либо на выход Q, при CE = «0». Синхросигнал CLK поступает на вход триггера постоянно, но срабатывание (запись внешних данных) происходит исключительно в тех тактах, в которых на вход CE подана лог. «1».
Путём генерации сигнала CE, устанавливаемого в лог. «1» в течение одного такта синхросигнала, и имеющего фиксированный период, составляющий натуральное число тактов, осуществляется синхронизация на пониженной частоте, кратной опорной частоте.
Триггер с входом CE может быть получен из элементарного D-триггера путём добавления двух транзисторов, реализующих входной мультиплексор (рис. 1). Большинство семейств ПЛИС содержит регистры, снабжённые входом CE, представляющие собой технологические примитивы, оптимизированные на уровне топологии ИС. В отсутствие необходимости использования разрешения синхронизации на вход CE подаётся постоянный разрешающий сигнал.
Рис. 1. Организация элементарного триггера с входом CE
Для второго случая, когда синхросигнал получен путём деления опорной частоты на дробный коэффициент, использование принципа разрешения синхронизации невозможно вследствие необходимости срабатывания по нисходящему и по восходящему по фронтам опорного синхросигнала в различных тактах. В данном случае для построения делителя частоты придётся пренебречь рекомендациями и использовать для формирования синхросигнала логические ресурсы. Во избежание гонок в комбинационной логике необходимо предусмотреть подачу входных сигналов таким образом, чтобы в течение времени срабатывания выходной комбинационной схемы изменял своё состояние только один входной сигнал.
Данный принцип построения делителя актуально использовать в двух случаях:
• отсутствие свободных блоков формирования частоты в ПЛИС архитектуры FPGA;
• использование ПЛИС архитектуры CPLD, не имеющих блоков формирования частоты.
В качестве примера можно рассмотреть связку ПЛИС архитектуры CPLD, микроконтроллера AVR фирмы Atmel, функционирующего на частоте 16 МГц, и опорного генератора синхросигнала с частотой 40МГц. Очевидна необходимость построения делителя частоты средствами ПЛИС, формирующего синхросигнал микроконтроллера путём деления опорной частоты на коэффициент 2,5.
Ниже рассмотрены две модели делителей частоты, формирующие синхросигналы различной формы:
• синхросигнал, полученный путём деления опорной частоты на дробный коэффициент;
• синхросигнал, полученный путём деления опорной частоты на натуральный коэффициент, но имеющий равную длительность высокого и низкого уровней в течение периода;
• сигналы, полученные путём деления опорной частоты на натуральный коэффициент, применяемые для разрешения синхронизации функциональных блоков и узлов, тактируемых опорным сигналом.
Рассмотрим примеры построения двух делителей частоты с дробными коэффициентами деления.
Рис. 2. Интерфейс делителя частоты с коэффициентами деления 1.5 и 3.0
Сначала необходимо определить интерфейс делителя частоты. На рис. 2 показан интерфейс для делителя с коэффициентами деления 1.5 и 3.0.
Входы делителя частоты ограничены двумя системными сигналами асинхронной установки начальных значений RST (активный высокий уровень) и синхросигналом CLK, задающим опорную тактовую частоту. Далее будем рассматривать синхронизацию по переднему фронту, при которой срабатывание регистров происходит при смене сигнала на входе CLK с низкого на высокий уровень.
Выходы делителя разделены на две группы. Первая группа выходов состоит из сигналов, предназначенных для непосредственного тактирования функциональных узлов, блоков и регистров. Эти сигналы подаются на входы синхронизации триггеров и имеют длительность высокого уровня максимально приближенную к длительности низкого уровня.
Вторая группа сигналов включает сигналы разрешения синхронизации CEO (Clock Enable Output), полученные на основе деления опорной частоты на натуральное число, и имеющие длительность высокого уровня, равную одному такту опорной частоты CLK. Сигналы из второй группы выходов характеризуются одной частотой и фиксированным сдвигом во времени на определённое число тактов опорной частоты. Выходы CEO ориентированы на синхронизацию функциональных узлов и блоков на пониженной частоте путём управления по цепям разрешения синхронизации CE (Clock Enable).
К сигналам первой группы предъявляются требования по стабильности переходного процесса, обеспечивающие срабатывание синхронизируемых узлов и блоков строго в нужные моменты времени. Требования стабильности были рассмотрены в статье [1].
Функционирование и внутреннюю организацию делителя частоты на коэффициенты 1.5 и 3.0 поясняет временная диаграмма на рис. 3.
Сформировать изображённые на диаграмме синхросигналы CLKDVxxx возможно только с использованием комбинационной логической схемы. Как известно, переключения комбинационной логики могут носить много ступенчатый характер, вызванный одновременным прохождением сигналов по различным промежуточным каскадам, что может приводить к многократным переключениям выходного сигнала в течение времени, отведённого на реакцию комбинационной схемы на входные воздействия. Подобная ситуация недопустима на выходе делителя частоты, ибо выходной сигнал должен изменять своё состояние ровно два раза за один период. Для устранения данного эффекта предлагается подавать на комбинационную схему сигналы с внутренних регистров таким образом, чтобы не происходили одновременные переключения двух и более входных сигналов.
В основе делителя лежит конечный автомат [2], непрерывно функционирующий по циклу 00-01-10, формирующий своими состояниями сигналы CEO_DV3X и CEO_DV3X_1T. Промежуточный сигнал DL_STATE_1 получается путём фиксации сигнала CEO_DV3X_1T триггером, работающим по заднему фронту синхросигнала CLK.
Высокий уровень на выходе CLKDV1X5 формируется при условии совпадения закрашенных серым цветом значений промежуточных сигналов.
Рис. 3. Диаграмма работы делителя с коэффициентами деления 1.5 и 3.0
Выходной сигнал CLKDV3X0 формируется путём логического сложения (в положительной логике) сигналов CEO_DV3X_1T (CNTR_STATE[1]) и DL_STATE_1. Нетрудно заметить, что данное техническое решение обеспечивает равенство длительности высокого и низкого логических уровней в течение одного периода.
Далее приводится поведенческая HDL-модель, описывающая рассмотренный делитель частоты на языке Verilog:
`timescale 1ns / 1ps
/////////////////////////////////////////////////////////////
// Company: Argon
// Engineer: FPGA-Mechanic
//
// Create Date: 16:27:50 03/16/2011
// Design Name: Clock Deviders
// Module Name: MCLKDIV_3X_V10
// Target Devices: PLD, FPGA or ASIC
// Tool versions: Xilinx ISE 10.1.03
// Description: Clock Frequency Divider by 1.5 and 3.0
// With Synchronous and Asynchronous Outputs
// Revision: 1.0
// Revision 1.0 - File Created
/////////////////////////////////////////////////////////////
module MCLKDIV_3X_V10(
input CLK, // Sys. Clock
input RST, // Asynch. Reset
output CLKDV1X5, // Asynch. CL-Output Clock/1.5
// Divided Frequency (H:L=1:2)
output CLKDV3X0, // Asynch. CL-Output Clock/3
// Divided Frequency (H:L=1:1)
output CEO_DV3X, // Synch. FF-Output Clock Enable
// Pulse (Clock/3 Frequency)
output CEO_DV3X_1T // Synch. FF-Output Clock Enable
// Pulse Delay 1T
);
// Internal signals declaration:
reg [1:0] CNTR_STATE;
reg DL_STATE_1;
//------------------------------------------
// Mod.3 Counter:
always @ (posedge CLK, posedge RST)
if(RST)
CNTR_STATE <= 2'd0;
else
case(CNTR_STATE)
2'd0 :
CNTR_STATE <= 2'd1;
2'd1 :
CNTR_STATE <= 2'd2;
default : // States 2 and 3:
CNTR_STATE <= 2'd0;
endcase
//------------------------------------------
// Clock-Enable Outputs:
assign CEO_DV3X = CNTR_STATE[0];
assign CEO_DV3X_1T = CNTR_STATE[1];
//------------------------------------------
// Delay for CNTR_STATE[1]:
always @ (CLK, RST, CNTR_STATE[1])
if(RST)
DL_STATE_1 <= 0;
else if(!CLK)
DL_STATE_1 <= CNTR_STATE[1];
//------------------------------------------
// Asynchronous Outputs:
assign CLKDV1X5 = (~CLK & CNTR_STATE[0]) | (CLK & DL_STATE_1);
assign CLKDV3X0 = CNTR_STATE[1] | DL_STATE_1;
//------------------------------------------
endmodule
Рассмотренный делитель частоты, в частности, может быть использован для генерации синхросигналов шин PCI, функционирующих на частотах 33 и 66 МГц, при использовании опорной частоты 100 МГц.
Делитель частоты с коэффициентами 2.0 и 4.0 в рамках данной статьи не рассматривается, ибо не относится к делителям с дробными коэффициентами деления и реализуется достаточно просто.
Рис. 4. Интерфейс делителя частоты с коэффициентами деления 2.5 и 5.0
На рис. 4 представлен интерфейс делителя с коэффициентами 2.5 и 5.0. Данный делитель построен по рассмотренным выше принципам, но имеет в основе более сложный автомат, формирующий внутренние сигналы и сигналы CEO.
Функционирование делителя с коэффициентами 2.5 и 5.0 поясняет диаграмма на рис. 5. Конечный автомат имеет четырёхразрядный внутренний регистр состояний и работает в цикле 0001-0100-0010-1000-1100. Сигналы CEO_DV5X и CEO_DV5X_2T получены на основе младших разрядов состояния автомата. Сигнал DL_STATE_1 формируется путём фиксации сигнала CEO_DV5X_2T по заднему фронту опорного синхросигнала CLK.
Рис. 5. Диаграмма работы делителя с коэффициентами деления 2.5 и 5.0
Сигнал CLKDV2X5 получен путём логического сложения (в положительной логике) сигналов CEO_DV5X (CNTR_STATE[0]) и DL_STATE_1.
Сигнал CLKDV5X0 получен путём логического сложения (в положительной логике) сигналов CNTR_STATE[3] и DL_STATE_1.
Сигналы, формируемые разрядами состояний автомата CNTR_STATE[0] и CNTR_STATE[1], могут быть использованы для синхронизации функциональных блоков и узлов с помощью механизма разрешения синхронизации Clock Enable. Данные разряды состояния дублируются на интерфейсе сигналами CEO_DV5X и CEO_DV5X_2T.
Далее приводится поведенческая HDL-модель, описывающая делитель частоты с коэффициентами 2.5 и 5.0 на языке Verilog:
`timescale 1ns / 1ps
/////////////////////////////////////////////////////////////
// Company: Argon
// Engineer: FPGA-Mechanic
//
// Create Date: 16:27:50 03/16/2011
// Design Name: Clock Deviders
// Module Name: MCLKDIV_5X_V10
// Target Devices: PLD, FPGA or ASIC
// Tool versions: Xilinx ISE 10.1.03
// Description: Clock Frequency Divider by 2.5 and 5.0
// With Synchronous and Asynchronous Outputs
// Revision: 1.0
// Revision 1.0 - File Created
/////////////////////////////////////////////////////////////
module MCLKDIV_5X_V10(
input CLK, // Sys. Clock
input RST, // Asynch. Reset
output CLKDV2X5, // Asynch. CL-Output Clock/2.5
// Divided Frequency (H:L=2:5)
output CLKDV5X0, // Asynch. CL-Output Clock/5
// Divided Frequency (H:L=1:1)
output CEO_DV5X, // Synch. FF-Output Clock Enable
// Pulse (Clock/5 Frequency)
output CEO_DV5X_2T // Synch. FF-Output Clock Enable
// Pulse Delay 2T
);
// Internal signals declaration:
reg [3:0] CNTR_STATE;
reg DL_STATE_1;
//------------------------------------------
// Mod.5 Counter:
always @ (posedge CLK, posedge RST)
if(RST)
CNTR_STATE <= 4'd1;
else
case(CNTR_STATE)
4'd1 :
CNTR_STATE <= 4'd4;
4'd4 :
CNTR_STATE <= 4'd2;
4'd2 :
CNTR_STATE <= 4'd8;
4'd8 :
CNTR_STATE <= 4'd12;
4'd12 :
CNTR_STATE <= 4'd1;
default : // Other States :
CNTR_STATE <= 4'd1;
endcase
//------------------------------------------
// Clock-Enable Outputs:
assign CEO_DV5X = CNTR_STATE[0];
assign CEO_DV5X_2T = CNTR_STATE[1];
//------------------------------------------
// Delay for CNTR_STATE[1]:
always @ (CLK, RST, CNTR_STATE[1])
if(RST)
DL_STATE_1 <= 0;
else if(!CLK)
DL_STATE_1 <= CNTR_STATE[1];
//------------------------------------------
// Asynchronous Outputs:
assign CLKDV2X5 = CNTR_STATE[0] | DL_STATE_1;
assign CLKDV5X0 = CNTR_STATE[3] | DL_STATE_1;
//------------------------------------------
endmodule
Цитированная литература
1. Борисенко Н.В. Технические аспекты построения управляющих автоматов при проектировании цифровых устройств на основе современных ПЛИС «Компоненты и технологии» №12.2011.
2. Алгебраическая теория автоматов, языков и полугрупп. Под редакцией М. Арбиба. Пер. с англ. М., «Статистика», 1975. 335 с.; с илл.
3. Spartan-6 Clocking Resources, www.xilinx.com/training/free-video-courses.htm#FPGA-ARC
4. Using Delay-Locked Loops in Spartan-II/IIE FPGAs, Xilinx Application Note XAPP174
Комментарии (16)
dernuss
21.07.2016 19:34Какая то у Вас древняя версия ise.
FPGA-Mechanic
21.07.2016 19:36Дык это же достаточно давнишний материал, ориентирован на архитектуру CPLD и старые FPGA, например — FLEX, Spartan-2, Virtex-1, в которых не было синтезаторов частоты.
Vladimir_Sklyar
21.07.2016 23:09+1Я бы еще отметил изящный стиль комментариев, не все так делают, а надо бы. Это стандарт компании или собственные наработки?
armature_current
22.07.2016 09:17Примеры не показательны. Просто комбинируете сигнал пониженной частоты за счет переднего/заднего фронтов входного сигнала. Как из 48МГц получить 3.6864МГц с такой моделью?
FPGA-Mechanic
22.07.2016 09:20Рассмотрены модели делителей с коэффициентами 1,5; 2,5; 3; 5.
48 МГц / 1.5 = 32 МГц
48 МГц / 2.5 = 19.2 МГц
48 МГц / 3 = 16 МГц
48 МГц / 5 = 9.6 МГц
Ответ — «никак». Не кратную частоту хотите.
FPGA-Mechanic
22.07.2016 09:2348 МГц — обычно несущая USB, 3.6864 МГц, также как 1.8432 МГц — частота UART для COM-порта.
Вообще для таких нужд обычно берут два независимых генератора.
На материнских платах используют специальные микросхемы ФАПЧ типа PLL, которые заточены под определённый чипсет и генерят все нужне частоты.
Sergei2405
22.07.2016 16:10Почему для DL_STATE_1 делается latch?
// Delay for CNTR_STATE[1]: always @ (CLK, RST, CNTR_STATE[1]) if(RST) DL_STATE_1 <= 0; else if(!CLK) DL_STATE_1 <= CNTR_STATE[1];
Это ограничивает максимальную частоту CLK. Потому что сигнал CNTR_STATE[1] должен установиться пока CLK=1.
Если переходные процессы CNTR_STATE «залезут» в фазу когда CLK=0, а это может быть, так как они должны закончится с неким tsetup (при этом tsetup много меньше 1/2 периода CLK) перед следующим положительным фронтом CLK.
И если переключение CNTR_STATE будут когда CLK уже стал нулевым, то эти переключения появятся и на DL_STATE_1. А это уже приведет к «фаршу» в этом месте
assign CLKDV1X5 = (~CLK & CNTR_STATE[0]) | (CLK & DL_STATE_1);
FPGA-Mechanic
25.07.2016 10:04CNTR_STATE — выход регистра Flip-Flop. Между ним и защёлкой-Latch нет никаких комбинационных схем, так что «фарша» быть не должно, только монотонный переходный процесс, ибо сигнал сформирован выходом регистра.
Вот касательно задержки — согласен. Задержка может возникнуть на длинных трассировочных ресурсах, тогда CNTR_STATE придёт на вход защёлки с опозданием, после заднего фронта CLK, что сломает алгоритм. Но, во-первых, для рассмотренной модели Duty Cycle для CLK должен быть 50%, поэтому «коротких единиц» относительно периода на CLK быть не должно. Во вторых, эту схему следует раскладывать в FPGA вручную, либо задать тесную область в кристалле для её Place&Route. Тогда длинных трассировок не будет.
Возможно, следовало в этом месте поставить Flip-Flop вместо Latch, работающий по negedge, но в старой альтере FLEX, такой зверь становится макросом с инвертором на клоке, так что не везде такой подход прокатил бы.
old_bear
23.07.2016 11:49IMHO, количество подводных камней в использовании логических ресурсов для генерации тактового сигнала слишком велико. Не проще ли свести задачу к кратности целому числу и воспользоваться сигналом разрешения? Например, удвоить опорные 100 МГц и получать нужные 66 МГц путём разрешения раз в три такта? Такой метод для все x.5 вариантов подходит.
Если выбранный чип не способен обеспечить работу логики на удвоенной частоте (даже с условием multicycle constraint-а для всех путей кроме сигнала разрешения), то можно сделать удвоение только для i/o (там ещё и DDR-примитивы могут помочь в формировании), а саму логику поставить работать с сигналом разрешения вида 2 такта через 1 и тому подобное. При этом остаётся только внимательно выполнить сопряжение работы внутренней логики и i/o, но это достаточно простая задача.
Главное преимущество таких решений в том, что мы переходим из области аналоговой неопределённости (при использовании логических ресурсов для формирования тактовых сигналов) в область чистой «цифры», когда достаточно отладить модель в симуляторе и убедиться что нет ошибок тайминга после P&R.FPGA-Mechanic
25.07.2016 09:21Очевидно, что генерация клока комбинационными ресурсами — решение не грамотное и не рекомендуемое в силу той же неопределённости задержек комбинационных цепей после PAR (P&R), вероятности гонок и «дребезга» веходного сигнала и т.п.
Рассмотренный пример под канонические правила проектирования не подходит. Но из всего бывают исключения.
Задача была такая: на CPLD разделить тактовую частоту на 2.5 и выдать «на улицу» для синхронизации другой микросхемы.
Другая задача в Spartan-2 из несущей 64МГц получить 42.7 при условии занятости всех DLL.
Ваш вариант — заставить работать все регистры на вдвое большей частоте и рулить их переключением раз в три такта для CPLD вообще нереален, ибо нет умножителя частоты, а для старых FPGA тоже крайне затруднителен, ибо упрёмся в предел работы самих регистров и глобальной сети синхросигнала.
Касательно ошибок тайминга после PAR — следует задать Timing Constraint по сгенерированному клоку — выходу описанной схемы. Я так и делал.old_bear
25.07.2016 11:09Я упоминал и второй вариант помимо всеобщего удвоения частоты. Для случая «выдать на улицу» он как раз подходит. Жаль, что вы его не заметили. ;)
Кстати, в первом из описываемых вами случаев вы производили измерения параметров полученного результата? Ведь «другая микросхема» вероятнее всего имела определённые требования к поступающему тактовому сигналу (я имею ввиду не только частоту). Конечно, довольно часто «всё работает и так», но, например, может перестать работать на другой партии устройств или, что хуже, сбоить время от времени с неявными симптомами.
Если не секрет, какой именно constraint вы задавали? Я сильно сомневаюсь в способности софта корректно применять constraint-ы, предназначенные для тактовых сигналов, к комбинаторной логике. И я не видел у Xilinx-а constraint-ов типа «отсутствие глитчей и гонок на этом отрезке логики». :)FPGA-Mechanic
25.07.2016 14:40Второй вариант какой-то неочевидный. В старых ПЛИСах DDR триггеров в IOB нет. Как раз вам повод опубликовать этот вариант.
В первом случае (CPLD серии XC9500) результат был проверен на осциллографе. Глитчей не было. И комбинационка там работает по принципу «изменение входной комбинации только по одному входу», как в коде Грея, так что гонок быть не должно. Синхросигнал на выходе не выровненный, Duty Cycyle 40%, согласно рис. 5. Это приемлемо.
Constraint был задан простой, период в нс и Duty Cycyle. Непосредственно в *.ucf прописан по сигналу выхода комбинационки. В Spartan2 все работало как часы.
AndriAnoBoTS
Было бы интереснее посмотреть на реализацию дробного делителя с произвольным коэффициентом деления. Да еще на MASH структуре порядка этак третьего.
FPGA-Mechanic
В современных ПЛИС лучше использовать блоки DCM или CMT. Они позволяют вторить клоковые чудеса!
AndriAnoBoTS
Это то понятно, вопрос не в практическом использовании, а в статье с разбором подобной модели.
Проблем с генерацией произвольных частот на практике как то уже давно не возникает.