Перейти к содержанию
    

Выходные сигналы ПЛИС и их "времянка"

Давно хотел спросить, но как-то руки не доходили... :)

 

Вот есть некие сигналы внутри ПЛИС (пусть для определенности какая-нибудь FPGA типа Cyclone от Altera):

 

bit       clock;
bit [7:0] data;

 

Задача вывести поток данных наружу на внешнее устройство: выходит шина данных (data) и сигнал тактовой частоты (clock). Есть требование, чтобы clock был сдвинут по фазе относительно данных - задержан, т.е. чтобы на том внешнем устройстве выполнялись требования по setup.

 

До сих пор задача успешно решалась так: в PLL заводилось два клока - один системный (например, 100 МГц), второй вспомогательный (200 МГц), сдвинутый относительно системного на четверть периода (2.5 нс). Данные выходят наружу через выходные триггеры IO элементов ПЛИС, которые тактируются системным клоком, а clock выходит наружу тоже через выходной триггер IO элемента, но подается он на вход данных триггера, а тактируется этот триггер вышеуказанным вспомогательным высокочастотным клоком, сдвинутым на 2.5 нс. Таким образом, на выходе получаются данные и клок без перекосов и с четко выдержанной времянкой. Все это работает.

 

Но есть сомнение. Как-то все это кажется сложновато и некрасиво - есть подозрение, что можно вывести клок с заданной задержкой без всяких подобных наворотов, а просто обконстрейнив. На "некрасивость" еще указывает то, что квартус на этот финт выдает предупреждение:

 

Warning: PLL "ClkGen|pllclkgen:PLLClkGen|altpll:altpll_component|pll" output port clk[0] feeds output pin "SCLK" via non-dedicated routing -- jitter performance depends on switching rate of other design elements. Use PLL dedicated clock outputs to ensure jitter performance

 

Понятно, что страшного ничего нет, но нехорошо.

 

Какие мнения? Как делать правильно?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Какие мнения? Как делать правильно?

 

Ну, например, вывести клок наружу через dedicated output c CLK0, а недра затактировать с CLK1, задав в параметрах PLL нужные фазовые взаимоотношения между ними... Как-то так. По крайней мере варнинг умрет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну, например, вывести клок наружу через dedicated output c CLK0, а недра затактировать с CLK1, задав в параметрах PLL нужные фазовые взаимоотношения между ними... Как-то так. По крайней мере варнинг умрет.

Да, варнинг-то не сильно беспокоит (это просто как бы симптом). А выводить клок через специальный пин - это привязка к цоколевке, тож не сильно удобно, если этот пин сильно далеко от основной шины. Просто думается, что видимо можно как-то констрейном задать, но опыта в этом деле нету. По идее как-то указать задержку сигнала от указанной группы. Все усугубляется тем, что данные выходят уже из выходных регистров IO. Там еще есть программируемая задержка в самом IO элементе, можно ее задействовать. Но это тоже не нравится - значения там чаще всего не те, какие нужны, и сильная привязка к конкретной ПЛИС.

 

Еще вариант - не размещать выхонные сигнады в триггеры IO и просто задать констрейны задержек от внутренних регистров до пинов. Что скажете?

 

P.S. Там есть еще одно мелкое обстоятельсво - поток выходной нерегулярный, есть паузы, когда все стоит (и данные, и клок, управляется по внутреннему сигналу разрешения), если выводить клок на dedicated pin, то с такой блокировкой видятся трудности.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да, варнинг-то не сильно беспокоит (это просто как бы симптом). А выводить клок через специальный пин - это привязка к цоколевке, тож не сильно удобно, если этот пин сильно далеко от основной шины. Просто думается, что видимо можно как-то констрейном задать, но опыта в этом деле нету. По идее как-то указать задержку сигнала от указанной группы. Все усугубляется тем, что данные выходят уже из выходных регистров IO. Там еще есть программируемая задержка в самом IO элементе, можно ее задействовать. Но это тоже не нравится - значения там чаще всего не те, какие нужны, и сильная привязка к конкретной ПЛИС.

 

Еще вариант - не размещать выхонные сигнады в триггеры IO и просто задать констрейны задержек от внутренних регистров до пинов. Что скажете?

 

P.S. Там есть еще одно мелкое обстоятельсво - поток выходной нерегулярный, есть паузы, когда все стоит (и данные, и клок, управляется по внутреннему сигналу разрешения), если выводить клок на dedicated pin, то с такой блокировкой видятся трудности.

Тогда Ваш вариант, и других вариантов пожалуй нет. Если мудрить констрейнами, то квартус начнет вытягивать времянки путем расставления буферов и удлинения разводки, а это, мягко говоря, фигня. Ну или выходной клок формировать тоже IO-триггером, тактируемым отдельным внутренним клоком, в два раза более быстрым, чем выходной клок. И не говорить квартусу (да он и не поймет), что этот выход - клок.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Еще вариант - не размещать выхонные сигнады в триггеры IO и просто задать констрейны задержек от внутренних регистров до пинов. Что скажете?

К сожалению, в этом случае Вы столкнётесь с зависимостью задержек от температуры и питания ядра, причём в различных партиях микросхем эти зависимости могут заметно отличаться.

 

Т.к. я работал только с Xilinx FPGA, то и нижеперечисленные подходы ориентированы на ресурсы присущие Xilinx FPGA. Думаю в FPGA, есть только 2 варианта создания гарантированного временного сдвига между сигналами:

1. Если есть возможность, то использовать фазосдвигатели в PLL/DCM. В крайнем случае, если есть элементы задержки во входном буфере CLK, то можно используя их получить 2 ветви CLK разведенных во времени (но в этом случае, хоть и в слабой форме, уже будут иметь место все вышеперечисленных зависимости от температуры и т.д.).

2. Работать на очень большой частоте внутри ПЛИС, и выходные сигналы формировать по различным фронтам этого высокочастотного clock (например: по 1 положительному фронту выставлять данные, по 1 отрицательному - clock, затем подождать несколько тактов и продолжить всё с начала) - но этот подход работает только для низкочастотных интерфейсов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В FPGA от XILINX очень удобно использовать блоки DCM - Digital Clock Manager. Блоки PLL (DLL), входящие в их состав, выдают 4 клока, сдвинутых между собой на 90 градусов. Таким образом, используя подходящий клок, можно получить нужные задержки. Кроме того, если не ошибаюсь, можно также задавать задержку между входным и выходным клоком, используя параметры CLKOUT_PHASE_SHIFT и PHASE_SHIFT. Вероятно, нечто похожее есть и у Альтеры.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В FPGA от XILINX очень удобно использовать блоки DCM - Digital Clock Manager. Блоки PLL (DLL), входящие в их состав, выдают 4 клока, сдвинутых между собой на 90 градусов. Таким образом, используя подходящий клок, можно получить нужные задержки. Кроме того, если не ошибаюсь, можно также задавать задержку между входным и выходным клоком, используя параметры CLKOUT_PHASE_SHIFT и PHASE_SHIFT. Вероятно, нечто похожее есть и у Альтеры.

Интересно если в альтере это диствительно есть? Написана программа - которая выводит данные .Требования вывести те же данные, но с другого места с задеркой. :smile3046: есть ли смысл писать программу для задержки или есть ещё какие то способы

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Давно хотел спросить, но как-то руки не доходили... :)

 

Вот есть некие сигналы внутри ПЛИС (пусть для определенности какая-нибудь FPGA типа Cyclone от Altera):

 

bit       clock;
bit [7:0] data;

 

Задача вывести поток данных наружу на внешнее устройство: выходит шина данных (data) и сигнал тактовой частоты (clock). Есть требование, чтобы clock был сдвинут по фазе относительно данных - задержан, т.е. чтобы на том внешнем устройстве выполнялись требования по setup.

 

До сих пор задача успешно решалась так: в PLL заводилось два клока - один системный (например, 100 МГц), второй вспомогательный (200 МГц), сдвинутый относительно системного на четверть периода (2.5 нс). Данные выходят наружу через выходные триггеры IO элементов ПЛИС, которые тактируются системным клоком, а clock выходит наружу тоже через выходной триггер IO элемента, но подается он на вход данных триггера, а тактируется этот триггер вышеуказанным вспомогательным высокочастотным клоком, сдвинутым на 2.5 нс. Таким образом, на выходе получаются данные и клок без перекосов и с четко выдержанной времянкой. Все это работает.

 

Но есть сомнение. Как-то все это кажется сложновато и некрасиво - есть подозрение, что можно вывести клок с заданной задержкой без всяких подобных наворотов, а просто обконстрейнив. На "некрасивость" еще указывает то, что квартус на этот финт выдает предупреждение:

 

Warning: PLL "ClkGen|pllclkgen:PLLClkGen|altpll:altpll_component|pll" output port clk[0] feeds output pin "SCLK" via non-dedicated routing -- jitter performance depends on switching rate of other design elements. Use PLL dedicated clock outputs to ensure jitter performance

 

Понятно, что страшного ничего нет, но нехорошо.

 

Какие мнения? Как делать правильно?

 

Не кажется Вам, что перемудрили?

Сравните полученный для FPGA Tco и требуемый Tsu...

Если Tclk - Tco > Tsu - то и не каких проблем быть не должно (Tclk - период тактовой)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Интересно если в альтере это диствительно есть? Написана программа - которая выводит данные .Требования вывести те же данные, но с другого места с задеркой. :smile3046: есть ли смысл писать программу для задержки или есть ещё какие то способы

Да, есть, блоки PLL имеют кучу выходов, каждый со своей заданной задержкой. А вот писать программу для задержки точно нет смысла, есть смысл поставить регистр, тактируемый сдвинутым клоком, инвертированным клоком, или поставить конвейер на N регистров, если задержать надо более, чем на 1 период клока.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

До сих пор задача успешно решалась так: в PLL заводилось два клока - один системный (например, 100 МГц), второй вспомогательный (200 МГц), сдвинутый относительно системного на четверть периода (2.5 нс).

 

Интересно, а чем плохо просто из PLL вытащить два клока 100 МГц и 100 МГц, сдвинутые на четверть периода. Первый тактирует выходные D-триггеры, а второй тупо наружу?

Или расчет строится на то, что при тактировании триггеров разными клоками компилятор разместит их в глобальных шинах и задержка там будет минимальна, т.е. лишенго сдвига по времени не будет (при условии одинаковых выходных триггеров и самое главное одинаковых нагрузочных емкостей)?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

dxp, правильно вам quartus наругался, клок ходит по проводам, которые для данных предназначены. И неприятность этого заключается не только в разбеге фаз и зависимости от условий. Так как клок покидает глобальную сеть, P&R и STA начинают учитывать не только глобальную сеть клока, но и "отросток", который идет к выходным буфферам. В результате, в узких местах будет надублирована логика, что увеличит площадь, что еще ухудшит разводку и еще надублируется логика. Если действительно узко, CRC какой-нибудь.

 

Чтобы избавиться от отростка при формировании выходного клока, можно применить трюк:

Что у вас есть - два клока с гарантированным PLL-ем сдвигом фаз и готовые констрейны о нем - о них заботятся quartus или ISE.

Предполагается, что сдвиг не слишком маленький, чтобы были трудности при передаче данных из регистра в регистр в разных доменах. На VHDL этого примерно так, а вы уложитесь в пару строк:

signal reg_r : std_logic; -- инвертируется на каждом
                  -- переднем фронте системного клока sys_clk
signal reg_f : std_logic;           -- сюда значение копируется из reg_r на каждом
                  -- заднем фронте системного клока sys_clk
-- если теперь про-XOR-ит их и инвертировать, то получим эквивалент sys_clk
....
process(sys_clk)
begin
   if rising_edge(sys_clk) then
      if reset='1' then
        reg_r <= '0';     -- нужен какой-нибудь сброс. 
      else                              -- В железе это не важно, но могут возникнуть трудности при моделировании.
        reg_r <= not reg_r;
      end if;
   end if;
end process;

process(sys_clk)
begin
   if falling_edge(sys_clk) then   -- если очень не хочется, то сброс можно не делать,
      reg_f <= reg_r;          --  но нужен встроенный в ячейку инвертор клока.
   end if;
end process;

process(fast_clk)
begin
   if rising_edge(fast_clk) then
      out_clk <= not (reg_f xor reg_r); -- тоже самое, что и закомментированная строка ниже
--      out_clk <= sys_clk
   end if;
end process;

 

Если знать ограничения на сигналы, да сопоставить их с температурой и напряжением, то допустимых некрасивых решений может оказаться много. В таких случаях интересно делать тупо, то есть, сначала рассмотреть решение, которое приводит к минимальным зависимостям от внеших условий и разводки. Например, как писал во втором пункте Boris_TS, задрать частоту.

Частота умножается в два раза в PLL (DCM), выход подается на буффер глобальной сети клока и оттуда поступает к тактовым входам выходных буфферов и выходного клока, и данных. Выходной клок формируется как данные (смотри выше), а не берется с выхода PLL и тем более не проходит напрямую к ножке. Чтобы не тратить зря логику, нужно сделать clock enable для основной части схемы. А чтобы не греть напрасно все вокруг, надо постараться сделать этот clock enable на глобальном буффере клока. В идеале, клок из PLL идет на два глобальных буффера, один для вывода, другой для остальной схемы. В VirtexII-pro я HyperTransport так делал, там клок тоже на 90 градусов сдвинут, ввод/вывод у меня работал на 400 MHz, а основная схема на 200MHz.

 

Минимальный разбег фаз выходов будет, если используются регистры в выходных буфферах тактируемые общим клоком разведенным по глобальной сети. Ну, по назначению когда инструмент используется, то его точность наилучшая. Как правило.

 

Пусть клок, данные и вся схема вместе дрожат от джиттеров PLL-ки, чем порознь.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не кажется Вам, что перемудрили?

Сравните полученный для FPGA Tco и требуемый Tsu...

Если Tclk - Tco > Tsu - то и не каких проблем быть не должно (Tclk - период тактовой)

Честно говоря, не понял вашего замечания. Не могли бы вы уточнить, что имелось в виду. Напомню, у меня есть данные и клок, клок должен быть сдвинут (задержан) относительно данных, я реализую это путем размещения выходного регистра данных в триггерах IO элементов ПЛИС, а клок тоже в таком же триггере IO элемента, но подаю его на вход данных (не на тактовый), а на тактовый вход этого триггера подаю вдвое более быстрый клок, сдвинутый на четверть периода основого клока (2.5 нс в моем случае). Таким образом, на выходе четко и гарантировано присутствуют данные с малым "перекосом" и клок, сдвинутый четко на указанную величину.

 

Интересно, а чем плохо просто из PLL вытащить два клока 100 МГц и 100 МГц, сдвинутые на четверть периода. Первый тактирует выходные D-триггеры, а второй тупо наружу?

Или расчет строится на то, что при тактировании триггеров разными клоками компилятор разместит их в глобальных шинах и задержка там будет минимальна, т.е. лишенго сдвига по времени не будет (при условии одинаковых выходных триггеров и самое главное одинаковых нагрузочных емкостей)?

Такая мысль тоже посещала, но взяло сомнение насчет временных соотношений. Ведь в случае пропускания клока через триггер выходного элемента имеем четкое соотношение в виду жесткой связности клоков. А тут если просто на выход клок метнуть, кто гарантирует, что он выйдет с четкой задержкой относительно данных, протактированных вторым клоком (ловим-то ведь единицы и доли наносекунд)? Ведь у него совершенно другой путь наружу в отличие от варианта с тактированием клока другим - сдвинутым высокочастотным.

 

К тому же, преимуществ никаких все равно не видно - все та же возня с клоками - их надо два, надо сдвиг, т.е. все упирается в наличие соответсвующей аппаратной приблуды (PLL).

 

dxp, правильно вам quartus наругался, клок ходит по проводам, которые для данных предназначены. И неприятность этого заключается не только в разбеге фаз и зависимости от условий. Так как клок покидает глобальную сеть, P&R и STA начинают учитывать не только глобальную сеть клока, но и "отросток", который идет к выходным буфферам. В результате, в узких местах будет надублирована логика, что увеличит площадь, что еще ухудшит разводку и еще надублируется логика. Если действительно узко, CRC какой-нибудь.

Проблемы в целом, связанные с пусканием клока по цепям данных, мне понятны. Но ведь тут-то все же просто - вывели клок через триггер выходного элемента, какие тут могут быть проблемы с джиттером и прочим? Похоже, что квартус тут формально оценивает - раз вывели клок, получите предупреждение.

 

Чтобы избавиться от отростка при формировании выходного клока, можно применить трюк:

Что у вас есть - два клока с гарантированным PLL-ем сдвигом фаз и готовые констрейны о нем - о них заботятся quartus или ISE.

Предполагается, что сдвиг не слишком маленький, чтобы были трудности при передаче данных из регистра в регистр в разных доменах. На VHDL этого примерно так, а вы уложитесь в пару строк:

...
process(fast_clk)
begin
   if rising_edge(fast_clk) then
      out_clk <= not (reg_f xor reg_r); -- тоже самое, что и закомментированная строка ниже
--      out_clk <= sys_clk
   end if;
end process;

Это что, весь этот наворот только для того, чтобы вывести сигнал клока в разряд данных? :)

 

Частота умножается в два раза в PLL (DCM), выход подается на буффер глобальной сети клока и оттуда поступает к тактовым входам выходных буфферов и выходного клока, и данных. Выходной клок формируется как данные (смотри выше), а не берется с выхода PLL и тем более не проходит напрямую к ножке.

Неужели нету средств просто завести клок в сигналы данных? Ну, буфер какой-нить для этого использовать... Надо будет поэскпериментировать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Неужели нету средств просто завести клок в сигналы данных? Ну, буфер какой-нить для этого использовать... Надо будет поэскпериментировать.

 

господа, я что то не понимаю или как. что мешает вывести комбинаторно ИНВЕРТИРОВАННЫЙ клок? Не нужны никакие дополнительные выходы PLL, усложнение логики(удвоение системного клока) и т.д. и т.п. Если есть DDRIO то "проблема" вообще решается тривиально и просто(даже warning не будет), на виртуальном инверторе. В этом случае фронт клока будет стоять в середине окна данных и принять его можно будет без проблем.

 

Проверено на многих ФПГА, для частот до 180 МГц, работает без нареканий.

 

 

PS. правда при этом разводка на плате сделана с выравниваем длин шины.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

господа, я что то не понимаю или как. что мешает вывести комбинаторно ИНВЕРТИРОВАННЫЙ клок? Не нужны никакие дополнительные выходы PLL, усложнение логики(удвоение системного клока) и т.д. и т.п.

++

Всегда так делали, правда, не на сотнях МГц, но суть от этого не меняется.

Разве только речь идёт о DDR, которая по обоим фронтам работает

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

господа, я что то не понимаю или как. что мешает вывести комбинаторно ИНВЕРТИРОВАННЫЙ клок? Не нужны никакие дополнительные выходы PLL, усложнение логики(удвоение системного клока) и т.д. и т.п.

А вы знаете, какие временные соотношения будут в сигналов в том случае? Вот клок фиксирует сигнал данных в триггере IO элемента, далее сигнал через время Tco выходит из триггера и следует до выходного пина через всякие мультиплексоры, элементы задержки, минуя трехстабильный буфер и т.д. Это тоже вносит задержку. Экспериментально для циклонов это время составляет порядка 2.2 нс. Так вот вопрос: а вот этот самый клок, которым такировали вышеописанный триггер, если его пустить тупо напрямую на внешний пин, - какая у него будет задержка? Ведь у него-то путь совсем другой. Начиная с того, что он идет со слоя глобальных сигналов, и заканчивая тем, что он идет мимо триггера.

 

Даже если провести эксперимент и убедиться, что соотношение времянок в этом случае приемлемое, где гарантия, что это не сопадение и что это соотношение будет выполняться всегда? Я в доке что-то не находил инфы, что-либо утверждающей на этот счет. И вообще это сильно попахивает асинхронщиной. :)

 

Если есть DDRIO то "проблема" вообще решается тривиально и просто(даже warning не будет), на виртуальном инверторе. В этом случае фронт клока будет стоять в середине окна данных и принять его можно будет без проблем.

Т.е. если данные выводить точно на DQ, а клок на DQS? Ну, так это привязка к конкретным пинам, чего бы не очень хотелось, вообще-то.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...