Мур 1 1 декабря, 2016 Опубликовано 1 декабря, 2016 · Жалоба А расскажите, почему так произошло? Человек, что писал проект, не ПЛИСовец. Он не придавал значения аспектам архитектуры и поддержки\отладки проекта(спасибо хоть с комментариями постарался!). Получился тугой узел, развязать который сложно. А как вы считаете, почему так произошло? Секрет скорее всего во временах восстановления(после асинхронного сброса). Там болтанка фронтов(асинхронных по сути) плюсуется. ТаймКвест формально это не пропускает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
johan 0 2 декабря, 2016 Опубликовано 2 декабря, 2016 · Жалоба Коллега, а можете рассказать в двух словах, что это за чип (семейство), сколько там было ячеек занято, какие хоть частоты? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 14 декабря, 2016 Опубликовано 14 декабря, 2016 (изменено) · Жалоба Раз тема создана, то вопрос наверное будет по теме. Сейчас я в процессе изучения TimeQuest. Сильно не пинайте, поскольку английским я владею не очень... Собственно никак не улавливаю разницы между get_registers и get_keepers. Ну что такое get_registers понятно: это регистры (Ваш КЭП) А вот что такое get_keepers ? В чем разница между ними ? UPD А где можно достать примеры файлов SDC совместно с проектами ? На примерах как-то проще учиться... Изменено 14 декабря, 2016 пользователем Flip-fl0p Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Грендайзер 0 15 декабря, 2016 Опубликовано 15 декабря, 2016 (изменено) · Жалоба По поводу keepers и registers, честно говоря было бы самому неинтересно. Сколько не читал в мануалах понять не могу. Впрочем, как я для себя решил, registers это подмножество keepers, которые могут быть ещё и портами. Тогда встаёт вопрос разницы между keepers и ports. Так что, как я понял, в принципе по этому поводу можно особо не замарачиваться и использовать лишь registers и ports (если не прав, пусть более сведущие товарищи поправят). Что касается примеров, настоятельно рекомендую проштудировать TimeQuest User Guide, написанный товарищем Ryan Scoville. Правда я его на русском не видел, (как и вообще какой либо литературы по констрейнам, кроме нескольких статей Дениса Шехалева), так что учите аглицкий. Так же рекомендую почить статьи Дениса Шехалева в КИТ, о которых я уже упоминал. Изменено 15 декабря, 2016 пользователем Грендайзер Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 15 декабря, 2016 Опубликовано 15 декабря, 2016 (изменено) · Жалоба По поводу keepers и registers, честно говоря было бы самому неинтересно. Сколько не читал в мануалах понять не могу. Впрочем, как я для себя решил, registers это подмножество keepers, которые могут быть ещё и портами. Тогда встаёт вопрос разницы между keepers и ports. Так что, как я понял, в принципе по этому поводу можно особо не замарачиваться и использовать лишь registers и ports (если не прав, пусть более сведущие товарищи поправят). Что касается примеров, настоятельно рекомендую проштудировать TimeQuest User Guide, написанный товарищем Ryan Scoville. Правда я его на русском не видел, (как и вообще какой либо литературы по констрейнам, кроме нескольких статей Дениса Шехалева), так что учите аглицкий. Так же рекомендую почить статьи Дениса Шехалева в КИТ, о которых я уже упоминал. Спасибо за ответ. Статьи Дениса Шехалева я читаю, разбираю, но вопросов возникает больше чем ответов. С английским беда. Без словаря понимаю 30-50% слов. Изучать английский еще долго, чтобы корректно воспринимать литературу на английском. Но я стараюсь. Читаю понемногу, но очень тяжко идет... С примерами как-то проще было бы изучать и понимать литературу. Очень много вопросов возникает из-за того, что почти во всех книгах\гайдах показаны совсем примитивные примеры. Ну вот к примеру что такое set_multicycle_path вроде понятно - данные пишутся не каждый такт, а раз в несколько тактов. А вот наприимер у меня есть ситуация: CASE X16CLOCK_CNT IS -- Анализируем состояние счетчика 16 битных интервалов WHEN 7 => SAMPLE_REG(0) <= RX_SYNC; -- Первая выборка старт бита WHEN 8 => SAMPLE_REG(1) <= RX_SYNC; -- Вторая выборка старт бита WHEN 9 => SAMPLE_REG(2) <= RX_SYNC; -- Третяя выборка старт бита WHEN 10 => CASE SAMPLE_REG IS -- На 10 такте проверяем состояние регистра выборки WHEN "000" | "001" | "100" | "010" => START_BIT_FOUND <= '1'; -- Большая часть битов равна нулю - выставляем флаг старт бита WHEN OTHERS => START_BIT_FOUND <= '0'; -- Иначе это была помеха END CASE; WHEN OTHERS => NULL; -- В остальных случая ничего не делаем END CASE; Как рассматривать запись в регистры SAMPLE_REG ? С одной стороны данные в регистры пишутся не каждый такт. С другой стороны, есть промежуток когда данные в регистры пишутся каждый такт. И справедливо ли для этих регистров указать такие констрейны как set_multicycle_path. Т.е вот так: set_multicycle_path -from [get_registers {RX_SYNC}] -to [get_registers {SAMPLE_REG[0]}] -setup -end 7 set_multicycle_path -from [get_registers {RX_SYNC}] -to [get_registers {SAMPLE_REG[1]}] -setup -end 8 set_multicycle_path -from [get_registers {RX_SYNC}] -to [get_registers {SAMPLE_REG[2]}] -setup -end 9 Надеюсь со временем смогу разобраться в констрейнах... Изменено 15 декабря, 2016 пользователем Flip-fl0p Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Грендайзер 0 15 декабря, 2016 Опубликовано 15 декабря, 2016 · Жалоба Ммм... Мне кажется Вы не совсем понимаете назначение и как следствие суть констрейнов... Штука то не сложная. Суть состоит в том, что в процессе синтеза, соответствующий софт (тот же TimeQuet) оценивает временные задержки на пути прохождения данных и передаёт эти данные ситезатору/мапперу/роутеру. Те в свою очередь синтезируют необходимую логику в необходимом количестве, располагают её соответствующим образом на кристалле и протягивают линии данных (трассируют) так, что бы удовлетворить основным требованиям временных ограничений, а именно по setup и hold. Т.о. всем этим товарищам абсолютно всё равно куда, когда и что Вы пишете/читаете. Их заботят лишь временные соотношения между фронтами тактов. Т.о. в Вашем случае, достаточно лишь задать значение частоты тактового сигнала. set_multicycle_path используется в случае наличия более одного тактового домена (более одной тактовой частоты), что бы указать в какой момент данные изменятся на линии управляемой первой частотой и, в какой момент они должны быть защёлкнуты на линии данных управляемой второй частотой. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 15 декабря, 2016 Опубликовано 15 декабря, 2016 · Жалоба Ммм... Мне кажется Вы не совсем понимаете назначение и как следствие суть констрейнов... Штука то не сложная. Суть состоит в том, что в процессе синтеза, соответствующий софт (тот же TimeQuet) оценивает временные задержки на пути прохождения данных и передаёт эти данные ситезатору/мапперу/роутеру. Те в свою очередь синтезируют необходимую логику в необходимом количестве, располагают её соответствующим образом на кристалле и протягивают линии данных (трассируют) так, что бы удовлетворить основным требованиям временных ограничений, а именно по setup и hold. Т.о. всем этим товарищам абсолютно всё равно куда, когда и что Вы пишете/читаете. Их заботят лишь временные соотношения между фронтами тактов. Т.о. в Вашем случае, достаточно лишь задать значение частоты тактового сигнала. set_multicycle_path используется в случае наличия более одного тактового домена (более одной тактовой частоты), что бы указать в какой момент данные изменятся на линии управляемой первой частотой и, в какой момент они должны быть защёлкнуты на линии данных управляемой второй частотой. Суть то вроде понимаю - сообщить трассировщику данные о проекте, чтобы он его расположил в ячейках кристалла так, чтобы выполнялись временные ограничения. Т.е там где надо он регистры расположил подальше\или поближе. А вот что конкретно надо сообщать трассировщику (т.е что писать в SDC файле, улавливаю слабо) Ну понятно, что надо описать клоки, клоки порожденные PLL, нестабильность клока, задержки входных/выходных данных, и ложные пути которые нас не интересуют. А вот что ещё надо описывать ? Когда описывать. Почему ? Вот это уловить толком и не могу. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Грендайзер 0 15 декабря, 2016 Опубликовано 15 декабря, 2016 (изменено) · Жалоба Ну понятно, что надо описать клоки, клоки порожденные PLL, нестабильность клока, задержки входных/выходных данных, и ложные пути которые нас не интересуют. Ну вот, Вы сами всё знаете Это и описывайте. Вы ведь сейчас назвали констрейны которые необходимы в 90% случаев. Понятно, что если Вас не интересуют задержки входных/выходных, то их вам и не надо описывать. А описать клоки, клоки порожденные PLL, нестабильность клока - это, можно сказать, джентельменский набор, это нужно описывать во всех проектах. Единственное, что нужно описывать не только клоки порожденные PLL, но и все порожденные (производные) клоки. Клоки ведь можно взять не только с PLL, а скажем, с обычного счётчика... Ну и не забывайте про тактовые домены (я про это уже писал). Правда существуют нюансы связанные с некоторыми примитивами на кристалле, реализованными, скажем, аппаратно. Ну например та же pll, или скажем DDR блоки, которые создаются в коргенах. В этом случае придётся читать мануал... на этот блок, к сожалению на английском. Изменено 15 декабря, 2016 пользователем Грендайзер Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
EgorT 0 15 декабря, 2016 Опубликовано 15 декабря, 2016 · Жалоба Да уж, всё очень запутано. Не стал создавать отдельную тему, решил спросить в этой. Проблема банальная: не сходятся тайминги. Итак, описание. Есть ПЛИС Cyclone V (5CEBA9F23C8), к ней подключается ЦАП, на ПЛИС заводится частота, с ПЛИС на ЦАП выводится код и частота. Соответственно внутри ПЛИС генерируется частота для ЦАП 210 МГц с помощью PLL. Код в в ПЛИС очень простой. module X5_DAC( (*chip_pin = "M9"*) input clk_26M, (*chip_pin = "v6, U8, U7, U6, T8, T7, R7, R6, R5, P6, P7, N6, M6, M7"*) output reg [13:0] D_D, (*chip_pin = "W8"*) output wire D_CLK ); // alt_pll alt_pll( .refclk (clk_26M), // refclk.clk .rst (1'b0), // reset.reset .outclk_0 (D_CLK) // outclk0.clk ); // reg [8:0] period_cnt; reg pulse_ena; // always@(posedge D_CLK) begin period_cnt<=period_cnt+1'b1; pulse_ena<=&period_cnt; if (pulse_ena) D_D<=14'b1111_1111_1111_11; else D_D<=14'h0; end // endmodule Собственно, каждый раз как счетчик period_cnt переполняется на ЦАП выводятся все единицы. Теперь констрейны: #************************************************************** # Time Information #************************************************************** set_time_format -unit ns -decimal_places 3 #************************************************************** # Create Clock #************************************************************** create_clock -name {clk_26M} -period 38.461 -waveform { 0.000 19.230 } [get_ports {clk_26M}] #************************************************************** # Create Generated Clock #************************************************************** create_generated_clock -name {alt_pll|alt_pll_inst|altera_pll_i|general[0].gpll~FRACTIONAL_PLL|vcoph[0]} -source [get_pins {alt_pll|alt_pll_inst|altera_pll_i|general[0].gpll~FRACTIONAL_PLL|refclkin}] -duty_cycle 50/1 -multiply_by 202 -divide_by 5 -master_clock {clk_26M} [get_pins {alt_pll|alt_pll_inst|altera_pll_i|general[0].gpll~FRACTIONAL_PLL|vcoph[0]}] create_generated_clock -name {alt_pll|alt_pll_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|divclk} -source [get_pins {alt_pll|alt_pll_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|vco0ph[0]} ] -duty_cycle 50/1 -multiply_by 1 -divide_by 5 -master_clock {alt_pll|alt_pll_inst|altera_pll_i|general[0].gpll~FRACTIONAL_PLL|vcoph[0]} [get_pins {alt_pll|alt_pll_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|divclk}] create_generated_clock -name {clk_210M} -source [get_pins {alt_pll|alt_pll_inst|altera_pll_i|outclk_wire[0]~CLKENA0|inclk}] -duty_cycle 50/1 -multiply_by 1 -divide_by 1 -master_clock {alt_pll|alt_pll_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|divclk} [get_pins {alt_pll|alt_pll_inst|altera_pll_i|outclk_wire[0]~CLKENA0|outclk}] create_generated_clock -name {D_CLK} -source [get_pins {alt_pll|alt_pll_inst|altera_pll_i|outclk_wire[0]~CLKENA0|outclk}] -duty_cycle 50/1 -multiply_by 1 -divide_by 1 -master_clock {clk_210M} [get_ports {D_CLK}] #************************************************************** # Set Clock Uncertainty #************************************************************** set_clock_uncertainty -rise_from [get_clocks {alt_pll|alt_pll_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|divclk}] -rise_to [get_clocks {D_CLK}] -setup 0.420 set_clock_uncertainty -rise_from [get_clocks {alt_pll|alt_pll_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|divclk}] -rise_to [get_clocks {D_CLK}] -hold 0.130 set_clock_uncertainty -rise_from [get_clocks {alt_pll|alt_pll_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|divclk}] -fall_to [get_clocks {D_CLK}] -setup 0.420 set_clock_uncertainty -rise_from [get_clocks {alt_pll|alt_pll_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|divclk}] -fall_to [get_clocks {D_CLK}] -hold 0.130 set_clock_uncertainty -rise_from [get_clocks {alt_pll|alt_pll_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|divclk}] -rise_to [get_clocks {alt_pll|alt_pll_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|divclk}] -setup 0.400 set_clock_uncertainty -rise_from [get_clocks {alt_pll|alt_pll_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|divclk}] -rise_to [get_clocks {alt_pll|alt_pll_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|divclk}] -hold 0.070 set_clock_uncertainty -rise_from [get_clocks {alt_pll|alt_pll_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|divclk}] -fall_to [get_clocks {alt_pll|alt_pll_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|divclk}] -setup 0.400 set_clock_uncertainty -rise_from [get_clocks {alt_pll|alt_pll_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|divclk}] -fall_to [get_clocks {alt_pll|alt_pll_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|divclk}] -hold 0.070 set_clock_uncertainty -fall_from [get_clocks {alt_pll|alt_pll_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|divclk}] -rise_to [get_clocks {D_CLK}] -setup 0.420 set_clock_uncertainty -fall_from [get_clocks {alt_pll|alt_pll_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|divclk}] -rise_to [get_clocks {D_CLK}] -hold 0.130 set_clock_uncertainty -fall_from [get_clocks {alt_pll|alt_pll_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|divclk}] -fall_to [get_clocks {D_CLK}] -setup 0.420 set_clock_uncertainty -fall_from [get_clocks {alt_pll|alt_pll_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|divclk}] -fall_to [get_clocks {D_CLK}] -hold 0.130 set_clock_uncertainty -fall_from [get_clocks {alt_pll|alt_pll_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|divclk}] -rise_to [get_clocks {alt_pll|alt_pll_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|divclk}] -setup 0.400 set_clock_uncertainty -fall_from [get_clocks {alt_pll|alt_pll_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|divclk}] -rise_to [get_clocks {alt_pll|alt_pll_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|divclk}] -hold 0.070 set_clock_uncertainty -fall_from [get_clocks {alt_pll|alt_pll_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|divclk}] -fall_to [get_clocks {alt_pll|alt_pll_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|divclk}] -setup 0.400 set_clock_uncertainty -fall_from [get_clocks {alt_pll|alt_pll_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|divclk}] -fall_to [get_clocks {alt_pll|alt_pll_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|divclk}] -hold 0.070 set_clock_uncertainty -rise_from [get_clocks {clk_210M}] -rise_to [get_clocks {clk_210M}] -setup 0.400 set_clock_uncertainty -rise_from [get_clocks {clk_210M}] -rise_to [get_clocks {clk_210M}] -hold 0.060 set_clock_uncertainty -rise_from [get_clocks {clk_210M}] -fall_to [get_clocks {clk_210M}] -setup 0.400 set_clock_uncertainty -rise_from [get_clocks {clk_210M}] -fall_to [get_clocks {clk_210M}] -hold 0.060 set_clock_uncertainty -rise_from [get_clocks {clk_210M}] -rise_to [get_clocks {D_CLK}] -setup 0.420 set_clock_uncertainty -rise_from [get_clocks {clk_210M}] -rise_to [get_clocks {D_CLK}] -hold 0.120 set_clock_uncertainty -rise_from [get_clocks {clk_210M}] -fall_to [get_clocks {D_CLK}] -setup 0.420 set_clock_uncertainty -rise_from [get_clocks {clk_210M}] -fall_to [get_clocks {D_CLK}] -hold 0.120 set_clock_uncertainty -fall_from [get_clocks {clk_210M}] -rise_to [get_clocks {clk_210M}] -setup 0.400 set_clock_uncertainty -fall_from [get_clocks {clk_210M}] -rise_to [get_clocks {clk_210M}] -hold 0.060 set_clock_uncertainty -fall_from [get_clocks {clk_210M}] -fall_to [get_clocks {clk_210M}] -setup 0.400 set_clock_uncertainty -fall_from [get_clocks {clk_210M}] -fall_to [get_clocks {clk_210M}] -hold 0.060 set_clock_uncertainty -fall_from [get_clocks {clk_210M}] -rise_to [get_clocks {D_CLK}] -setup 0.420 set_clock_uncertainty -fall_from [get_clocks {clk_210M}] -rise_to [get_clocks {D_CLK}] -hold 0.120 set_clock_uncertainty -fall_from [get_clocks {clk_210M}] -fall_to [get_clocks {D_CLK}] -setup 0.420 set_clock_uncertainty -fall_from [get_clocks {clk_210M}] -fall_to [get_clocks {D_CLK}] -hold 0.120 #************************************************************** # Set Input Delay #************************************************************** #************************************************************** # Set Output Delay #************************************************************** set_output_delay -add_delay -max -clock [get_clocks {D_CLK}] 2.000 [get_ports {D_D[0]}] set_output_delay -add_delay -min -clock [get_clocks {D_CLK}] -1.500 [get_ports {D_D[0]}] set_output_delay -add_delay -max -clock [get_clocks {D_CLK}] 2.000 [get_ports {D_D[1]}] set_output_delay -add_delay -min -clock [get_clocks {D_CLK}] -1.500 [get_ports {D_D[1]}] set_output_delay -add_delay -max -clock [get_clocks {D_CLK}] 2.000 [get_ports {D_D[2]}] set_output_delay -add_delay -min -clock [get_clocks {D_CLK}] -1.500 [get_ports {D_D[2]}] set_output_delay -add_delay -max -clock [get_clocks {D_CLK}] 2.000 [get_ports {D_D[3]}] set_output_delay -add_delay -min -clock [get_clocks {D_CLK}] -1.500 [get_ports {D_D[3]}] set_output_delay -add_delay -max -clock [get_clocks {D_CLK}] 2.000 [get_ports {D_D[4]}] set_output_delay -add_delay -min -clock [get_clocks {D_CLK}] -1.500 [get_ports {D_D[4]}] set_output_delay -add_delay -max -clock [get_clocks {D_CLK}] 2.000 [get_ports {D_D[5]}] set_output_delay -add_delay -min -clock [get_clocks {D_CLK}] -1.500 [get_ports {D_D[5]}] set_output_delay -add_delay -max -clock [get_clocks {D_CLK}] 2.000 [get_ports {D_D[6]}] set_output_delay -add_delay -min -clock [get_clocks {D_CLK}] -1.500 [get_ports {D_D[6]}] set_output_delay -add_delay -max -clock [get_clocks {D_CLK}] 2.000 [get_ports {D_D[7]}] set_output_delay -add_delay -min -clock [get_clocks {D_CLK}] -1.500 [get_ports {D_D[7]}] set_output_delay -add_delay -max -clock [get_clocks {D_CLK}] 2.000 [get_ports {D_D[8]}] set_output_delay -add_delay -min -clock [get_clocks {D_CLK}] -1.500 [get_ports {D_D[8]}] set_output_delay -add_delay -max -clock [get_clocks {D_CLK}] 2.000 [get_ports {D_D[9]}] set_output_delay -add_delay -min -clock [get_clocks {D_CLK}] -1.500 [get_ports {D_D[9]}] set_output_delay -add_delay -max -clock [get_clocks {D_CLK}] 2.000 [get_ports {D_D[10]}] set_output_delay -add_delay -min -clock [get_clocks {D_CLK}] -1.500 [get_ports {D_D[10]}] set_output_delay -add_delay -max -clock [get_clocks {D_CLK}] 2.000 [get_ports {D_D[11]}] set_output_delay -add_delay -min -clock [get_clocks {D_CLK}] -1.500 [get_ports {D_D[11]}] set_output_delay -add_delay -max -clock [get_clocks {D_CLK}] 2.000 [get_ports {D_D[12]}] set_output_delay -add_delay -min -clock [get_clocks {D_CLK}] -1.500 [get_ports {D_D[12]}] set_output_delay -add_delay -max -clock [get_clocks {D_CLK}] 2.000 [get_ports {D_D[13]}] set_output_delay -add_delay -min -clock [get_clocks {D_CLK}] -1.500 [get_ports {D_D[13]}] Ну тут сначала описывается клок, который подаётся на ПЛИС, 26 МГц, потом клоки на PLL, потом описывается выходной клок, который идет на ЦАП (D_CLK, он же на ножке ПЛИС). Потом идут uncertainty, их генерирует сам таймквест, как и все эти длинные, ужасные имена в pll. Потом идут отношения выходного клока (D_CLK) с выходными данными (D_D), здесь указано все согласно с даташитом ЦАП. И естественно после компиляции таймквест ругается, слэк в setup summary отрицательный. Картинки из таймквеста прикреплены в архиве. Не понимаю, что еще нужно добавить к констрейнам, чтобы они выполнялись. Или неужели пятые циклоны настолько медленные, констрейны не выполняются и на 125 МГц, к слову на третьем циклоне по крайней мере на 125 МГц все в порядке. TQ.zip Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
bogaev_roman 0 15 декабря, 2016 Опубликовано 15 декабря, 2016 · Жалоба Не понимаю, что еще нужно добавить к констрейнам, чтобы они выполнялись. Или неужели пятые циклоны настолько медленные, констрейны не выполняются и на 125 МГц, к слову на третьем циклоне по крайней мере на 125 МГц все в порядке. Я, к примеру, архив не могу скачать и открыть, Вы так не можете картинки выложить со слэком по сетапу? Предположу, что скорее всего, данные сидят не в fast output register (соответственно программируемая задержка не задействована) и самое главное - частота реально пойдет на выход быстрее нежели установятся данные - создайте на pll сдвинутую по фазе частоту и пустите ее на выход (в зависимости от того, насколько слэк отрицательный). А так вообще то у Вас ограничения довольно жесткие - требуется обеспечить окно, шириной 2+1.5=3.5 нс, при том что период частоты 1/210=4.76нс. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
EgorT 0 16 декабря, 2016 Опубликовано 16 декабря, 2016 · Жалоба Я, к примеру, архив не могу скачать и открыть, Вы так не можете картинки выложить со слэком по сетапу? Предположу, что скорее всего, данные сидят не в fast output register (соответственно программируемая задержка не задействована) и самое главное - частота реально пойдет на выход быстрее нежели установятся данные - создайте на pll сдвинутую по фазе частоту и пустите ее на выход (в зависимости от того, насколько слэк отрицательный). А так вообще то у Вас ограничения довольно жесткие - требуется обеспечить окно, шириной 2+1.5=3.5 нс, при том что период частоты 1/210=4.76нс. Добавил картинки Да, данные не fast_output register, как же я мог забыть про это. Fast_output помогает, убирает слэки по сетапу, но появились слэки по холду, хоть и намного меньше) Думаю придется делать второй клок на PLL, сдвинутый по фазе. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
bogaev_roman 0 16 декабря, 2016 Опубликовано 16 декабря, 2016 · Жалоба Да, данные не fast_output register, как же я мог забыть про это. Fast_output помогает, убирает слэки по сетапу, но появились слэки по холду, хоть и намного меньше) Думаю придется делать второй клок на PLL, сдвинутый по фазе. Почитайте документацию AN433. А так если ошибки по холдам, то можно попробовать пустить частоту через DDR регистр (hi=1, low=0) и тогда на частоту также можно будет задействовать программируемые задержки. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
en-valb 0 23 января, 2017 Опубликовано 23 января, 2017 (изменено) · Жалоба Всем доброго времени суток! Что бы не плодить тем решил задать вопрос здесь. Использую Quartus Prime 15.1 Update 2. Есть в проекте несколько Verilog-овских модулей. Все модули соединены между собой в файле верхнего уровня. Файл верхнего уровня оформлен в схемном редакторе. Имеются файлы временных ограничений для каждого модуля. Как теперь все это дело вытащить на верхний уровень так что бы Quartus при компиляции производил разводку каждого модуля в соответствии со своим sdc файлом, и как из проекта верхнего уровня можно запускать временной анализ с помощью TimeQuest-а для каждого модуля в отдельности. Углубленно TimeQuest изучаю последнюю неделю, выполнил лабу http://fpga.in.ua/fpga/cad-pld/basic-quart...iz-proekta.html, потом проштудировал от и до (кроме последнего примера) TimeQuest для чайников от Дениса Шехалева. http://embedders.org/system/files/TimeQuest_for_dummies.pdf, вернулся к своему проекту закреплять полученные навыки и сразу же появился вопрос представленный выше. В связи с выше сказанным могут быть глупые вопросы. Прошу сильно не пинать. Забыл указать что первая ссылка не работает, нужно по запросу "ЛР6 _ Временной анализ проекта" в yandex открыть сохраненную копию. Изменено 23 января, 2017 пользователем en-valb Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aus 0 31 января, 2017 Опубликовано 31 января, 2017 · Жалоба Насколько я понимаю, констрейны просто позволяют сообщить Квартусу, насколько он свободно может развести описанную структуру в кристалле. Если нет описания клоков, он их видит, но не анализирует. Если клоки описаны, то он пытается развести с минимальными задержками, и выдает предупреждения. В случае слаков, их можно убрать либо изменениями в коде, либо с помощью констрейна мультиклоков. Естественно, перед этим нужно описать пути, которые анализировать нет необходимости. В проект можно прицепить кучу .sdc файлов и для любого модуля описать оригинальные клоки. Поправьте меня, если ошибаюсь. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Грендайзер 0 3 февраля, 2017 Опубликовано 3 февраля, 2017 (изменено) · Жалоба Здравствуйте. У меня не совсем вопрос, а скорее просьба немного помочь. Написал код для Altera. Затем написал констрейны. Вроде всё хорошо, но... Понадобилось мне перенести этот код на Xilinx... на довольно старенький кристалл. Ну и соответственно понадобилось синопсисовские констрейны переписать под ксайлинсовские ucf. И тут вообще обзац. Мог бы кто нибудь помочь переписать мои констрейны. set_time_format -unit ns -decimal_places 3 derive_clock_uncertainty create_clock -name CLK -period 20.000 [get_ports {CLK}] create_generated_clock -name SCLK -source [get_ports {CLK}] -divide_by 2 [get_registers {SPI:SPI_inst|SCLK}] set_multicycle_path -setup -from [get_clocks {CLK}] -to [get_clocks {SCLK}] -start 2 set_multicycle_path -hold -from [get_clocks {CLK}] -to [get_clocks {SCLK}] -start 1 set_false_path -from [get_clocks {SCLK}] -to [get_clocks {CLK}] set_false_path -from [get_clocks {CLK}] -to [get_clocks {SCLK}] set_output_delay -clock {SCLK} -max 4 [get_ports {MOSI}] set_output_delay -clock {SCLK} -min -4 [get_ports {MOSI}] set_output_delay -clock {SCLK} -max 7 [get_ports {CS}] set_output_delay -clock {SCLK} -min -7 [get_ports {CS}] create_clock -name SCLK_virt -period 40.000 set_multicycle_path -setup -from [get_clocks {CLK}] -to [get_clocks {SCLK_virt}] -start 2 set_multicycle_path -hold -from [get_clocks {CLK}] -to [get_clocks {SCLK_virt}] -start 1 set_input_delay -clock {SCLK_virt} -clock_fall -max 0.500 [get_ports {MISO}] set_input_delay -clock {SCLK_virt} -clock_fall -min 0.500 [get_ports {MISO}] Ну с входными и выходными задержками я разберусь, как и с мультициклами. Но как быть с синхросигналом, который является производным от данного и виртуальным клоком? Вообщем пока всё на что меня хватило это NET "CLK" TNM_NET = CLK; TIMESPEC "TS_CLK" = PERIOD "CLK" 20 ns HIGH 50%; Изменено 3 февраля, 2017 пользователем Грендайзер Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться