Jump to content
    

LVDS DDR данные из АЦП в ПЛИС

Что не так делаю?

Почему вместо синуса вижу корявый меандр?

Не реагирует на изменение амплитуды сигнала.

С какой стороны младшие биты? (c D0 или с D6)

Тактирую ПЛИС по CLK_OUT от АЦП

 

АЦП ADS6145

http://www.ti.com/lit/ds/symlink/ads6145.pdf

Спасибо.

 

 

 

 

   component IBUFGDS
  --    -- synopsys translate_off
      generic( DIFF_TERM : boolean :=  FALSE);
  --    -- synopsys translate_on
      port ( I  : in    std_logic; 
             IB : in    std_logic; 
             O  : out   std_logic);
   end component;
   attribute IOSTANDARD of IBUFGDS : component is "DEFAULT";
   attribute DIFF_TERM of IBUFGDS : component is "FALSE";
   attribute BOX_TYPE of IBUFGDS : component is "BLACK_BOX";
   
   component IBUFDS
      -- synopsys translate_off
      generic( DIFF_TERM : boolean :=  FALSE);
      -- synopsys translate_on
      port ( I  : in    std_logic; 
             IB : in    std_logic; 
             O  : out   std_logic);
   end component;
   attribute IOSTANDARD of IBUFDS : component is "DEFAULT";
   attribute DIFF_TERM of IBUFDS : component is "FALSE";
   attribute BOX_TYPE of IBUFDS : component is "BLACK_BOX";


begin

data_out <= out13 & out12 & out11 & out10 & out9 & out8 & out7 & out6 & out5 & 
                out4 & out3 & out2 & out1 & out0 ;

clk_out <= USER_CLK;


   IBUFGDS_1 : IBUFGDS
      port map (I=>SMA_DIFF_CLK_IN_P,
                IB=>SMA_DIFF_CLK_IN_N,
                O=>USER_CLK);


   IBUFDS_1 : IBUFDS
      port map (I=>HDR2_28_SM_11_P,
                IB=>HDR2_26_SM_11_N,
                O=>DDR_1);
   
   
   IBUFDS_2 : IBUFDS
      port map (I=>HDR2_32_DIFF_3_P,
                IB=>HDR2_30_DIFF_3_N,
                O=>DDR_2);
....

process(USER_CLK)
begin

        if (USER_CLK = '1') then
      
        out0 <= DDR_0;
        out2 <= DDR_1;
        out4 <= DDR_2;
        out6 <= DDR_3;
        out8 <= DDR_4;
        out10<= DDR_5;
        out12<= DDR_6;
        

        elsif (USER_CLK = '0') then
        
        out1 <= DDR_0;
        out3 <= DDR_1;
        out5 <= DDR_2;
        out7 <= DDR_3;
        out9 <= DDR_4;
        out11 <= DDR_5;
        out13 <= DDR_6;

        end if;

end process;

 

 

 

Share this post


Link to post
Share on other sites

Что не так делаю?

Почему вместо синуса вижу корявый меандр?

Не реагирует на изменение амплитуды сигнала.

С какой стороны младшие биты? (c D0 или с D6)

Тактирую ПЛИС по CLK_OUT от АЦП

 

АЦП ADS6145...

 

ПЛИС и инструментарий не указан - ХЗ чем вы там синтезите,

 

но по своему опыту скажу: с такими аппаратными фичами Xilinx как DDR, SERDES, PLL, IODELAY и др. лучше ИМХО

обращаться путём наглого вставления примитивов в HDL, иначе ISE будет тупить очень сильно (он конечно тупит и с примитивами - но значительно меньше). Дифференциальные буферы не поленились вставить в ввиде примитивов - вот и IDDR нужно также.

 

Там у IDDR, есть помниться несколько режимов работы, задающихся генериками. А что вам тут ваш синтезатор сделал из вашего кода ХЗ? И вставил ли он вообще IDDR? И если вставил, то с какими настройками?

 

И ещё режет глаз:

generic( DIFF_TERM : boolean := FALSE);

это так и задумано? место на плате много и снаружи не поленились резюки по 100Ом запаять?

 

P.S. и ещё не ясно, что с клоком из АЦП - на какой тип ноги он заведен (GCLK, MRCC, SRCC или CLOCK_DEDICATED_ROUTE = false) ?

P.S.2 констреинты есть какие-нибудь?

Share this post


Link to post
Share on other sites

Дифференциальные буферы не поленились вставить в ввиде примитивов - вот и IDDR нужно также.

Вот тут, похоже, правда, а то из Вашего процесса какая-то ерунда должна синтезироваться, а не DDR-буфер.

Share this post


Link to post
Share on other sites

ПЛИС и инструментарий не указан - ХЗ чем вы там синтезите,

 

но по своему опыту скажу: с такими аппаратными фичами Xilinx как DDR, SERDES, PLL, IODELAY и др. лучше ИМХО

обращаться путём наглого вставления примитивов в HDL, иначе ISE будет тупить очень сильно (он конечно тупит и с примитивами - но значительно меньше). Дифференциальные буферы не поленились вставить в ввиде примитивов - вот и IDDR нужно также.

 

Там у IDDR, есть помниться несколько режимов работы, задающихся генериками. А что вам тут ваш синтезатор сделал из вашего кода ХЗ? И вставил ли он вообще IDDR? И если вставил, то с какими настройками?

 

И ещё режет глаз:

generic( DIFF_TERM : boolean := FALSE);

это так и задумано? место на плате много и снаружи не поленились резюки по 100Ом запаять?

 

P.S. и ещё не ясно, что с клоком из АЦП - на какой тип ноги он заведен (GCLK, MRCC, SRCC или CLOCK_DEDICATED_ROUTE = false) ?

P.S.2 констреинты есть какие-нибудь?

 

 

Xilinx ML507, virtex5, ise14.

С диф. сигналами работаю впервые, нарисовал диф. приёмники в схематике,

сделал view hdl, и исправил расширение файла.

CLK_OUT заведен на GCLK:

SMA_DIFF_CLK_IN_N          bank 3       IO_L6P_GC_3    LOC= "H14"
SMA_DIFF_CLK_IN_N          bank 3       IO_L6N_GC_3    LOC= "H15"

 

Кстати, интересно, можно ли его завести на Clock Capable I/Os?:

Предусмотрел возможность на плате, чтобы не тянуть clock через sma разъёмы.

   IO_L9N_CC_SM0N_13        bank13       LOC=AE34
   IO_L9P_CC_SM0P_13         bank13       LOC=AF34

 

Прошу прощения, не совсем понятна фраза:

Дифференциальные буферы вставить в виде примитивов?

 

Про IDDR впервые слышу, спасибо. Если можно в двух словах зачем он? С ходу не разобрался.

 

В ucf файле у меня так:

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

 

NET  SMA_DIFF_CLK_IN_N    LOC="H15";   # Bank 3, Vcco=2.5V, No DCI      
NET  SMA_DIFF_CLK_IN_P    LOC="H14";   # Bank 3, Vcco=2.5V, No DCI  

//////////////////////////////////
//D0_D1
NET  HDR2_22_SM_10_N      LOC="T34";   # Bank 11, Vcco=2.5V or 3.3V user selectable by J20 (SYSMON External Input: VAUXN[10]) J4-22
NET  HDR2_24_SM_10_P      LOC="U33";   # Bank 11, Vcco=2.5V or 3.3V user selectable by J20 (SYSMON External Input: VAUXP[10]) J4-24

//D2_D3
NET  HDR2_26_SM_11_N      LOC="U31";   # Bank 11, Vcco=2.5V or 3.3V user selectable by J20 (SYSMON External Input: VAUXN[9]) J4-26
NET  HDR2_28_SM_11_P      LOC="U32";   # Bank 11, Vcco=2.5V or 3.3V user selectable by J20 (SYSMON External Input: VAUXP[9]) J4-28

//D4_D5
NET  HDR2_30_DIFF_3_N     LOC="V33";   # Bank 13, Vcco=2.5V or 3.3V user selectable by J20 (SYSMON External Input: VAUXN[8]) J4-30
NET  HDR2_32_DIFF_3_P     LOC="V32";   # Bank 13, Vcco=2.5V or 3.3V user selectable by J20 (SYSMON External Input: VAUXP[8]) J4-32

----------

 

остальные ноги типа:

HDR2_22_SM_10_N      IO_L18N_SM10N_11  
HDR2_24_SM_10_P      IO_L18P_SM10P_11

--

 

Про терминирование большое спасибо, внешних резюков нет, недочитал просто.

Думал, что оно жестко привязано внутри к ноге, а что сгенерировал конвертор из схематика не разобрался.

Share this post


Link to post
Share on other sites

Про IDDR впервые слышу, спасибо. Если можно в двух словах зачем он? С ходу не разобрался.

IDDR - буфер, который входные данные по двум фронтам защёлкивает, на выходе имеем D0 и D1.

Можно тут почитать.

А тут применительно к Вашему девайсу.

Share this post


Link to post
Share on other sites

Xilinx ML507, virtex5, ise14.

С диф. сигналами работаю впервые, нарисовал диф. приёмники в схематике,

сделал view hdl, и исправил расширение файла.

CLK_OUT заведен на GCLK:

NET  SMA_DIFF_CLK_IN_N    LOC="H15";   
NET  SMA_DIFF_CLK_IN_P    LOC="H14";   

//D0_D1
NET  HDR2_22_SM_10_N      LOC="T34"; 
NET  HDR2_24_SM_10_P      LOC="U33";  
...

 

 

Похоже, я забыл указать в констрейнах что это LVDS сигнал:

NET  SMA_DIFF_CLK_IN_N    LOC="H15"|IOSTANDARD = LVDS_25;  
NET  SMA_DIFF_CLK_IN_P    LOC="H14"|IOSTANDARD = LVDS_25;

Edited by Ar-han

Share this post


Link to post
Share on other sites

Я, кажется, понял, это тут совсем не нужно:

process(USER_CLK)
begin

        if (USER_CLK = '1') then
      
        out0 <= DDR_0;
        out2 <= DDR_1;
        out4 <= DDR_2;
        out6 <= DDR_3;
        out8 <= DDR_4;
        out10<= DDR_5;
        out12<= DDR_6;
        

        elsif (USER_CLK = '0') then
        
        out1 <= DDR_0;
        out3 <= DDR_1;
        out5 <= DDR_2;
        out7 <= DDR_3;
        out9 <= DDR_4;
        out11 <= DDR_5;
        out13 <= DDR_6;

        end if;

end process;

 

, а нужны IDDR модули после диф. приёмников))

 

   IDDR_0 : IDDR    
      port map (C=>USER_CLK,
                CE=>VPP,
                D=>DDR_0,    
                R=>GRND,
                S=>GRND,
                Q1=>out0,
                Q2=>out1);

 

 

Share this post


Link to post
Share on other sites

Долго же Вы понимали :)

 

И всё же проблема актуальна ))

Так выглядит синус f = 1 мгц, амплитудой 0.9 Вольт

post-67135-1404222875_thumb.jpg

Share this post


Link to post
Share on other sites

И всё же проблема актуальна ))

Биты у Вас попутаны. На какой частоте АЦП работает?

Share this post


Link to post
Share on other sites

Биты у Вас попутаны. На какой частоте АЦП работает?

 

АЦП на 125 МГц, ломаю голову, где напутал биты.

Откуда ярко выраженные ступеньки в сигнале?

Вот синус 1 мгц, с амплитудой 100 - 200 мВ.

post-67135-1404224239_thumb.jpg

Share this post


Link to post
Share on other sites

Что не так делаю?

Почему вместо синуса вижу корявый меандр?

Не реагирует на изменение амплитуды сигнала.

А симулировать проект пробовали?

Скажем записать в файл данные от синусоиды и сделать имитатор АЦП. И из файла выдать синусоиду...

 

А уже потом говорить, что данные кривые...

 

Share this post


Link to post
Share on other sites

А симулировать проект пробовали?

Скажем записать в файл данные от синусоиды и сделать имитатор АЦП. И из файла выдать синусоиду...

 

А уже потом говорить, что данные кривые...

 

Я вместо диф. приёмников пилу подсовывал, вчера вроде бы нормальная пила была.

Share this post


Link to post
Share on other sites

Могу предложить, но для этого Вам понадобиться наладить SPI (если его пока нет), перевести АЦП в режим синхронизации, т.е. для регистра 0x0A записать в TEST PATTERNS режим Custom pattern (101) и в качестве Custom Pattern записать, например, 14'b10101010101010. На приёмной стороне принимаете Вашу тестовую посылку, смотрите, какие биты попутаны. Быстрее всёго они будут приниматься в неправильном порядке, но этот порядок будет сохраняться, тогда меняете местами в соответствии с вашей эталонной последовательностью и можно работать. Если порядок следования бит меняется от запуска к запуску (если тайминги плохо прописаны, то такое и будет), тогда делаете устройство которое при включении будет производить синхронизацию и подключать принимаемые биты в правильном порядке.

 

АЦП на 125 МГц, ломаю голову, где напутал биты.

Что делать уже написал, но попробуйте, для начала, и частоту понизить, чтоб хотя бы результат правильный получить, а потом будете поднимать.

 

А уже потом говорить, что данные кривые...

Данные не кривые, просто принимаются неправильно, нужно поменять порядок следования бит и всё будет в порядке.

 

Share this post


Link to post
Share on other sites

Могу предложить, но для этого Вам понадобиться наладить SPI (если его пока нет), перевести АЦП в режим синхронизации, т.е. для регистра 0x0A записать в TEST PATTERNS режим Custom pattern (101) и в качестве Custom Pattern записать, например, 14'b10101010101010. На приёмной стороне принимаете Вашу тестовую посылку, смотрите, какие биты попутаны. Быстрее всёго они будут приниматься в неправильном порядке, но этот порядок будет сохраняться, тогда меняете местами в соответствии с вашей эталонной последовательностью и можно работать. Если порядок следования бит меняется от запуска к запуску (если тайминги плохо прописаны, то такое и будет), тогда делаете устройство которое при включении будет производить синхронизацию и подключать принимаемые биты в правильном порядке.

 

 

Что делать уже написал, но попробуйте, для начала, и частоту понизить, чтоб хотя бы результат правильный получить, а потом будете поднимать.

 

 

Спасибо! До SPI еще не добрался, и с моими темпами, похоже, не скоро ))

Генератор впаян, но есть возможность тактировать из вне.

Совет полезный, нужно будет попробовать. Жаль с ходу не ясно в чём баг.

 

Тут-то я правильно описал атрибут IDDR "OPPOSITE_EDGE"?

       component IDDR
      -- synopsys translate_off
      generic( INIT_Q1 : bit :=  '0';
               INIT_Q2 : bit :=  '0';
               DDR_CLK_EDGE : string :=  "OPPOSITE_EDGE";
               SRTYPE : string :=  "SYNC");
      -- synopsys translate_on
      port ( D  : in    std_logic; 
             CE : in    std_logic; 
             C  : in    std_logic; 
             S  : in    std_logic; 
             R  : in    std_logic; 
             Q1 : out   std_logic; 
             Q2 : out   std_logic);
   end component;

 

Без входного сигнала:

post-67135-1404225860_thumb.jpg

Edited by Ar-han

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...