Jump to content

    

Digi

Свой
  • Content Count

    239
  • Joined

  • Last visited

Community Reputation

0 Обычный

About Digi

  • Rank
    Местный
  • Birthday 07/10/1978

Контакты

  • Сайт
    Array
  • ICQ
    Array

Recent Profile Visitors

3232 profile views
  1. DDC пришлось раскидать на разные тактовые частоты. Основная частота заходит на PLL а с PLL 8 частот с такими же параметрами заходят на свои DDC. Так как если их повесить на одну, то время компиляции значительно возрастает и ни один DDC не работает. Хотя предупреждений у TimeQuest нет. Перестаёт корректно работать CIC фильтр.
  2. На первом рисунке это что в в стандартной корке DDIO. А вот во втором случае возникнет проблема синхронизацией полуслов. Потому что FRM это не просто делённые CLK. Кажется так...
  3. А вот так как раз и не получилось сгруппировать. Выдавал ошибку. Поэтому и задал вопрос. Так разве можно ? Если да, то ещё раз попробую сделать и понять, что было не так.
  4. Да, скорее всего на входах, но суть это не меняет. Анализ не проводится. Но при попытке увязать это всё в одну кучу, результат - невозможность вытянуть времянки
  5. Вот например, как быть в таком случае ? Все частоты одинаковы, за исключением A_CLK. Изначально добавлял в одну группу {A_FRMCLK1 A_CLK1} в другую FRMCLKx, отдельно каждую из DDC_CLK* и отдельно OUT_CLK. Возникала ситуация, что на выходе CDC не всегда защёлкивались верные данные. Так как Quartus некоторые биты утягивал совершенно в другую сторону кристалла, а так как между этими клоками не происходил анализ времянок, то и ошибок для него не было. Если замешать все клоки в одну группу, то время компиляции возрастало до неразумных пределов, и времянки везде недотягивали до требуемых. Проект становился совершенно неработоспособным.
  6. Продолжаю войну с впихиванием проекта в Cyclone 10 GX. На данный момент он состоит из 8 DDC, добился, что 7 из них работают нормально, хочу их разводку зафиксировать. Как можно зафиксировать их разводку, что бы при перекомпиляции она не менялась ? И другой вопрос, менее актуальный. Как указать фиттеру, размещать части модуля рядом друг с другом, а не раскидывать их по кристаллу. Это чисто для эстетической оптимизации )) Сейчас размещение выглядит так:
  7. Неужели никто не занимается описанием input delay ? Или мои вопросы слишком сложные ?
  8. А по какому принципу нужно объединять клоки в группы ?
  9. # ADC1_CLK _________________________________ # ___________________________| |___________________________ # virtual clock _________________________________ # _________| |___________________________ # | | # skew_bre|skew_are skew_bfe|skew_afe # <------>|<------> <------>|<------> # _ | _________________ | _________________ # data _XXXXXXXXXXXXXXXXX____Rise_Data____XXXXXXXXXXXXXXXXX____Fall_Data____XX # set skew_bre 0.200; # Data invalid before the rising clock edge set skew_are 0.200; # Data invalid after the rising clock edge set skew_bfe 0.200; # Data invalid before the falling clock edge set skew_afe 0.200; # Data invalid after the falling clock edge # Input Delay Constraint set_input_delay -clock virtual_clock_adc -max [expr $adc_data_period/2 + $skew_afe] [get_ports {ADC1_D[*]}]; set_input_delay указывал относительно virtual clock Но тем не менее, даже если бы я его ошибочно указал, то Квартус должен был бы увеличить задержки, для того чтобы времянки были выполнены, а он этого не делает. Собственно из-за чего я и бьюсь с этим всем.
  10. Переделал проект под обычные регистры. По идее должно работать так же как и Intel GPIO Half-Rate. ADC1_D[*] - поток данных DDR выставляется на частоте 400 МГц 0 градусов. ADC1_CLK - 400 МГЦ (90 градусов) ADC1_FRM - 200 МГц (0 градусов) Структура такая: Проект для Q15 qddr.qar SDC: set_time_format -unit ns -decimal_places 3 derive_clock_uncertainty set adc_data_period 2.500 set adc_frame_preiod [expr $adc_data_period * 2] create_clock -name virtual_clock_adc -period $adc_data_period create_clock -name {ADC1_CLK} -period $adc_data_period [get_ports {ADC1_CLK}] -waveform { 0.625 1.875 } create_clock -name {ADC1_FRM} -period $adc_frame_preiod [get_ports {ADC1_FRM}] set_clock_groups -exclusive -group [get_clocks {ADC1_CLK ADC2_CLK virtual_clock_adc ADC1_FRM ADC2_FRM } ] #set_clock_groups -exclusive -group [get_clocks {ADC1_CLK virtual_clock_adc ADC1_FRM } ] #set_clock_groups -exclusive -group [get_clocks {ADC2_CLK virtual_clock_adc ADC2_FRM } ] # Edge-Aligned Dual Data Rate Source Synchronous Inputs # (Using a direct FF connection) # # For an edge-aligned Source Synchronous interface, the clock # transition occurs at the same time as the data transitions. # In this template, the clock is aligned with the beginning of the # data. The constraints below rely on the default timing # analysis (setup = 1/2 cycle, hold = 0 cycle). # # input _________________________________ # clock _________| |___________________________ # | | # skew_bre|skew_are skew_bfe|skew_afe # <------>|<------> <------>|<------> # _ | _________________ | _________________ # data _XXXXXXXXXXXXXXXXX____Rise_Data____XXXXXXXXXXXXXXXXX____Fall_Data____XX # set skew_bre 0.200; # Data invalid before the rising clock edge set skew_are 0.200; # Data invalid after the rising clock edge set skew_bfe 0.200; # Data invalid before the falling clock edge set skew_afe 0.200; # Data invalid after the falling clock edge # Input Delay Constraint set_input_delay -clock virtual_clock_adc -max [expr $adc_data_period/2 + $skew_afe] [get_ports {ADC1_D[*]}]; set_input_delay -clock virtual_clock_adc -min [expr $adc_data_period/2 - $skew_bfe] [get_ports {ADC1_D[*]}]; set_input_delay -clock virtual_clock_adc -max [expr $adc_data_period/2 + $skew_are] [get_ports {ADC1_D[*]}] -clock_fall -add_delay; set_input_delay -clock virtual_clock_adc -min [expr $adc_data_period/2 - $skew_bre] [get_ports {ADC1_D[*]}] -clock_fall -add_delay; # ************** False path ***************** set_false_path -setup -fall_from [get_clocks virtual_clock_adc] -rise_to [get_clocks ADC1_CLK] set_false_path -setup -rise_from [get_clocks virtual_clock_adc] -fall_to [get_clocks ADC1_CLK] set_false_path -hold -rise_from [get_clocks virtual_clock_adc] -rise_to [get_clocks ADC1_CLK] set_false_path -hold -fall_from [get_clocks virtual_clock_adc] -fall_to [get_clocks ADC1_CLK] Verilog: module top ( //ADS42LB69 // ADC1 input [3: 0] ADC1_D, input ADC1_CLK, input ADC1_FRM, // ADC2 input [3: 0] ADC2_D, input ADC2_CLK, input ADC2_FRM, output [15:0] ADC1_OUT, output [15:0] ADC2_OUT ); reg [3:0] a1_regout_hi; reg [3:0] a1_regout_lo; reg [3:0] a1_regout_lo_n; reg [7:0] a1_hr_regout_hi; reg [7:0] a1_hr_regout_lo; reg [7:0] a1_hr_regout_lo_n; wire [15: 0] gpio1_d; wire [15: 0] gpio2_d; //---- Full rate latch ---- always @(posedge ADC1_CLK) begin a1_regout_hi[3:0] <= ADC1_D[3:0]; a1_regout_lo[3:0] <= a1_regout_lo_n[3:0]; end always @(negedge ADC1_CLK) a1_regout_lo_n[3:0] <= ADC1_D[3:0]; //------- Half rate latch ------ always @(posedge ADC1_FRM) begin a1_hr_regout_hi[7:0] <= {a1_regout_hi[3:0], a1_regout_lo[3:0]}; a1_hr_regout_lo[7:0] <= a1_hr_regout_lo_n[7:0]; end always @(negedge ADC1_FRM) a1_hr_regout_lo_n[7:0] <= {a1_regout_hi[3:0], a1_regout_lo[3:0]}; //------------------------------ assign ADC1_OUT[15:0] = {a1_hr_regout_hi[7:0] , a1_hr_regout_lo[7:0] };
  11. Выкладываю тестовый проект. АЦП ADC42LB69. ПЛИС Cyclone 10GX. Ouartus 20.4 Prime Как это правильно сделать ? ADC_QDR_test.qar
  12. Конечно же читал. Просто код очень кривой. Даже сейчас , удалось заставить его работать нормально. Но как только я его запускаю из bootloadera, так начинается веселье. Порога или нормально стартует и работает, или виснет где то. От чего зависит, не понятно.... Что ещё хуже
  13. Вроде ситуация у всех наверное такая встречалась, или я один на такие грабли наступил ? Кто как описывал QDR интерфейс ?
  14. Я ожидаю получить на входе ADC_D[*] валидные данные не позднее 0,3 нс и не ранее 0,3 нс относительно фронтов виртуального клока. В каком периоде клока - не важно, но для всех каналов должно быть одинаково. Фактически для всех каналов это реализуемо на втором или третьем периоде клока. Но для начала в этом простом проекте с одним каналом не могу правильно описать то что хочу
  15. Так как это DDR, то add_delay нужен для задания ограничений заднего фронта. Он записан вместе с -clock_fall Тоже есть по этому поводу сомнения. Но у меня с выхода АЦП валидные данные выровнены относительно фронта тактового импульса. И я описываю, что launch clock будет виртуальный, и соответствует с началом шкалы, а latch clock (ADC1_CLK) физический и он приходит смещённый относительно данных и начала шкалы на 90 градусов. В случае если описывать set_input_delay относительно latch clock (ADC1_CLK), то да, -max должен быть, как вы и написали, <половине периода - tsetup > . Кстати, а не может ли быть проблема из-за того, что в моём случае клок не может прийти на триггер раньше чем данные ? Минимально возможный путь клока до регистра 3 нс, а данные 1.5 нс. Т.е. защёлкиваемые данные будут анализироваться со сдвигом на один такт И как это описать в таком случае ? Пробовал так, ошибки уходят, но работать от этого не начинает. Это правильная запись ? set_multicycle_path 2 -setup -from [get_clocks virtual_clock_adc] -to [get_clocks {ADC1_CLK} ] set_multicycle_path 1 -hold -from [get_clocks virtual_clock_adc] -to [get_clocks {ADC1_CLK} ] Ещё в догонку. Я указал set_input_delay -clock virtual_clock_adc -max [expr $adc_data_period/2 - $dv_bfe] ну и все остальные, как в примерах SDC от Xilinx, анализатор выдал вот такую картину. То есть запас по slack 3 нс, при периоде 2.5 нс. Т.е он ожидает данные на следующем периоде, а приходят они на период раньше и это для него нормально. Как такое может быть ?