顯示具有 PLL 標籤的文章。 顯示所有文章
顯示具有 PLL 標籤的文章。 顯示所有文章

2014年5月14日 星期三

ML605 GTX DRP TEST

ML605 GTX DRP TEST
target ML605, ISE 14.4

GTX 實在是太強大了,如果不學會用它就向跟不上流行似的!!!!!

PLL Output Divider generate gtx的時候會自動寫入attribute 不用自己改


generate gtx 之後可以使用ipcore裡面的範例來了解一下gtx內部結構
可參考LogiCORE IP Virtex-6 FPGA GTX Transceiver Wizard v1.12 User Guide http://physics.bu.edu/~wusx/download/AMC13/HTR/doc/ug516_v6_gtxwizard.pdf


line rate 可以自己輸入需要的值,如果想要在scope上面看到輸出的值,encoder要選none,refclk 會有固定的幾個頻率可以選,規則如下,可以選擇最適合的除數來進行頻率的調整,紅色是在ipcore裡面不提供的頻率範圍

因為要在ML605上經由Tx Rx SMA來測試,依照spec 要選refclk 125 MHz且在GTX_X0Y18 



每一個quadGTX都可以使用自己或是上面下面quadrefclk0,refclk1
其他GTX得設定先照預設的,產生完了以後打開ipcore_dir裡面的gtx project
裡面有範例的Frame generator Frame check,分別輸入gtx與檢查從gtx出來的資料是正確

我做了幾個小實驗來體會一下gtx
  1. 自動產生的ucf不會自動把輸出的pin設到GTX TX SMA
    所以把下列加入ucf , 並把gtx0_txdata 改成0xaa方便觀察頻率,
    bit file燒入板子後可以在scope上看到頻率500MHz , 1Gbps
NET TXN_OUT LOC=B2;
NET TXP_OUT LOC=B1;
ML605 上與GTX相關的SMA如下
NET SMA_TX_P LOC=B1;
NET SMA_TX_N LOC=B2;
NET SMA_RX_P LOC=D5;
NET SMA_RX_N LOC=D6;
NET SMA_REF_CLK_P LOC=F6;
NET SMA_REF_CLK_N LOC=F5;

  1. ipcore裡面的REFCLK0改成REFCLK1
    讓外接的SMA REFCLK 來動態改變 lane rate,refclklanerate的比例會根據在ipcore裡面的設定來改變
    ucf
    NET TXN_OUT LOC=B2;
    NET TXP_OUT LOC=B1;
    ####################### GTX reference clock constraints #######################
    NET Q4_CLK1_MGTREFCLK_PAD_N_IN LOC=F5;
    NET Q4_CLK1_MGTREFCLK_PAD_P_IN LOC=F6;
    
    ################################# mgt wrapper constraints #####################
    ##---------- Set placement for gtx0_gtx_wrapper_i/GTX_DUAL ------
    INST gtx_i/gtx0_gtx_i/gtxe1_i LOC=GTXE1_X0Y18;
    

    1. 測試DRPregister, ml605上的200 MHz osc拉近來,用來當DRPinour clk
      拿掉系統預設的DRP_CLK_IN

並將下列加入top levelcode,chipscope來改變DRPregister,用來改變頻率
signal DRP_CLK_IN : std_logic;

--------------------------------------------------------
osc_freqgen_in : IBUFGDS
port map (
O => DRP_CLK_IN, -- Clock buffer output
I => OSC_P, -- Diff_p clock buffer input
IB => OSC_N -- Diff_n clock buffer input
);
--------------------- chipscope ------------------------
gtx0_daddr_i <= tx_data_vio_sync_out_i(31 downto 24);
gtx0_den_i <= tx_data_vio_sync_out_i(23);
gtx0_di_i <= tx_data_vio_sync_out_i(22 downto 7);
gtx0_dwe_i <= tx_data_vio_sync_out_i(6);

gtx0_tx_data_vio_sync_in_i(31) <= gtx0_drdy_i;
gtx0_tx_data_vio_sync_in_i(30 downto 15) <= gtx0_drpdo_i;
gtx0_tx_data_vio_sync_in_i(14 downto 0) <= "000000000000000";

---------------------------------------------------------

產生bit file以後打開chipscope, 打開chipscope file\ipcore_dir\gtx\implement\chipscope_project.cpj

燒入bit file以後將設定的drp register拉到VIO Console


根據address table 有兩個address 0x1F 0x20


PLL 公式如下,fPLLClkinRefclk

現在設定的Lanerate1G,refclk 125 Mhz,code裡面看到的attribute


125x(4x4/1)x(2/4) = 125*8 = 1G check沒錯



DRP
  1. DWE 0
  2. DADDR 1F or 20
  3. DEN 1



drdyhigh表示讀成功,drpdo可以算出其他register的值




ipcore_dir generate600MHzregister
N2 2
D 4
M 1
N1 5
推算出register value
address:0x1F drpdo:0xb8c0
address:0x20 drpdo:0x0020


寫入DRP

  1. DWE 1
  2. DADDR 0x1F or 0x20
  3. DI 設入相對drpdo
  4. DEN 1   

可以看到scope上為624 mbps,我猜是因為600 mhzrefclk 不為125 ,所以會有誤差
所以動態改變GTX的方式有兩種,改變refclk或是改變DRP Register



PLL Output Pin

如何將pll 產生的clock輸出到output來控制其他IC
target spartan6,ISE14.4
一開始連doc都沒看就如下好傻好天真的把plloutput經由bufg送到pad
結果果然產生error ........

在使用pll的時候不要忘了相乘以後的頻率範圍要在spec上的VCO Freg範圍內, 不然error就會來找你拉!

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
library UNISIM;
use UNISIM.VComponents.all;

entity pll_out_top is
    Port ( 
    osc_200_p  : in  STD_LOGIC;
    osc_200_n  : in  STD_LOGIC;
    reset   : in  STD_LOGIC;
    pll_out0  : out  STD_LOGIC;
    pll_out1  : out  STD_LOGIC);

end pll_out_top;

architecture Behavioral of pll_out_top is
signal clkin  : std_logic;
signal clk_fb  : std_logic;
signal locked  : std_logic;
signal pll_clkout0,pll_clkout1 : std_logic;

begin

  -- Input Clock Buffer
  clkin1_ibuf : IBUFGDS
  port map (
    I  => osc_200_p,
    IB => osc_200_n,
    O  => clkin);
  
   PLL_BASE_inst : PLL_BASE
   generic map (
      BANDWIDTH => "OPTIMIZED",          
      CLKFBOUT_MULT => 4,        
      CLKFBOUT_PHASE => 0.0,   
      CLKIN_PERIOD => 5.0,           
    
      CLKOUT0_DIVIDE => 2,
      CLKOUT1_DIVIDE => 4,
      CLKOUT2_DIVIDE => 1,
      CLKOUT3_DIVIDE => 1,
      CLKOUT4_DIVIDE => 1,
      CLKOUT5_DIVIDE => 1,
    
      CLKOUT0_DUTY_CYCLE => 0.5,
      CLKOUT1_DUTY_CYCLE => 0.5,
      CLKOUT2_DUTY_CYCLE => 0.5,
      CLKOUT3_DUTY_CYCLE => 0.5,
      CLKOUT4_DUTY_CYCLE => 0.5,
      CLKOUT5_DUTY_CYCLE => 0.5,
     
      CLKOUT0_PHASE => 0.0,
      CLKOUT1_PHASE => 0.0,
      CLKOUT2_PHASE => 0.0,
      CLKOUT3_PHASE => 0.0,
      CLKOUT4_PHASE => 0.0,
      CLKOUT5_PHASE => 0.0,
      CLK_FEEDBACK => "CLKFBOUT",         
      COMPENSATION => "SYSTEM_SYNCHRONOUS", 
      DIVCLK_DIVIDE => 1,                   
      REF_JITTER => 0.1,                    
      RESET_ON_LOSS_OF_LOCK => FALSE       
   )
   port map (
      CLKFBOUT => clk_fb, 
      
      CLKOUT0 => pll_clkout0,
      CLKOUT1 => pll_clkout1,
      CLKOUT2 => open,
      CLKOUT3 => open,
      CLKOUT4 => open,
      CLKOUT5 => open,
      LOCKED => locked,     
      CLKFBIN => clk_fb,   
      CLKIN => clkin,       
      RST => reset            
   );  
  
  u_BUFG0  : BUFG PORT MAP (I => pll_clkout0, O => pll_out0);
  u_BUFG1  : BUFG PORT MAP (I => pll_clkout1, O => pll_out1);
  
end Behavioral;

Error
ERROR:Place:1205 - This design contains a global buffer instance, <u_BUFG0>,
driving the net, <pll_out0_OBUF>, that is driving the following (first 30)
non-clock load pins off chip.
< PIN: pll_out0.O; >
This design practice, in Spartan-6, can lead to an unroutable situation due
to limitations in the global routing. If the design does route there may be
excessive delay or skew on this net. It is recommended to use a Clock
Forwarding technique to create a reliable and repeatable low skew solution:
instantiate an ODDR2 component; tie the .D0 pin to Logic1; tie the .D1 pin to
Logic0; tie the clock net to be forwarded to .C0; tie the inverted clock to
.C1. If you wish to override this recommendation, you may use the
CLOCK_DEDICATED_ROUTE constraint (given below) in the .ucf file to demote
this message to a WARNING and allow your design to continue. Although the net
may still not route, you will be able to analyze the failure in FPGA_Editor.
CLOCK_DEDICATED_ROUTE = FALSE; >


ERROR:Place:1136 - This design contains a global buffer instance, <u_BUFG0>,
driving the net, <pll_out0_OBUF>, that is driving the following (first 30)
non-clock load pins.
< PIN: pll_out0.O; >
This is not a recommended design practice in Spartan-6 due to limitations in
the global routing that may cause excessive delay, skew or unroutable
situations. It is recommended to only use a BUFG resource to drive clock
loads. If you wish to override this recommendation, you may use the
CLOCK_DEDICATED_ROUTE constraint (given below) in the .ucf file to demote
this message to a WARNING and allow your design to continue.
< PIN "u_BUFG0.O" CLOCK_DEDICATED_ROUTE = FALSE; >


xilinxclock手冊裡面寫如果要從pll傳到pad必須經過ODDR2 buffer,而且ODDR2 的輸出必須經由OBUF送出,不可以在輸入FPGA中的其他邏輯,不然會有Package error

ERROR : PACK 2530 ::The dual data rate register "u_ODDR2_0" failed to join an OLOGIC component as required.




在圖上是接clkfbout但是也可以用再clkout0-5,drp的官方範例裡面有用到
code改成如下,便可解決以上的error
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
library UNISIM;
use UNISIM.VComponents.all;

entity pll_out_top is
    Port (
    osc_200_p  : in  STD_LOGIC;
    osc_200_n  : in  STD_LOGIC;
    reset   : in  STD_LOGIC;
    pll_out0_p  : out  STD_LOGIC;
    pll_out0_n  : out  STD_LOGIC;
    pll_out1_p  : out  STD_LOGIC;
    pll_out1_n  : out  STD_LOGIC);
end pll_out_top;

architecture Behavioral of pll_out_top is
signal clkin     : std_logic;
signal clk_fb     : std_logic;
signal locked     : std_logic;
signal pll_clkout0,pll_clkout1   : std_logic;
signal   clkbufout0,clkbufout1     : std_logic;
signal   n_clkbufout0,n_clkbufout1  : std_logic;
signal   oddr2out0,oddr2out1  : std_logic;
signal  pll_out0,pll_out1  : std_logic;

begin

  -- Input Clock Buffer
  clk_buf : IBUFGDS
  port map (
    I  => osc_200_p,
    IB => osc_200_n,
    O  => clkin);
 
   PLL_BASE_inst : PLL_BASE
   generic map (
      BANDWIDTH => "OPTIMIZED",
      CLKFBOUT_MULT => 4,      
      CLKFBOUT_PHASE => 0.0,   
                              
      CLKIN_PERIOD => 5.0,     
                               
      CLKOUT0_DIVIDE => 2,
      CLKOUT1_DIVIDE => 4,
      CLKOUT2_DIVIDE => 1,
      CLKOUT3_DIVIDE => 1,
      CLKOUT4_DIVIDE => 1,
      CLKOUT5_DIVIDE => 1,
      CLKOUT0_DUTY_CYCLE => 0.5,
      CLKOUT1_DUTY_CYCLE => 0.5,
      CLKOUT2_DUTY_CYCLE => 0.5,
      CLKOUT3_DUTY_CYCLE => 0.5,
      CLKOUT4_DUTY_CYCLE => 0.5,
      CLKOUT5_DUTY_CYCLE => 0.5,
      CLKOUT0_PHASE => 0.0,
      CLKOUT1_PHASE => 0.0,
      CLKOUT2_PHASE => 0.0,
      CLKOUT3_PHASE => 0.0,
      CLKOUT4_PHASE => 0.0,
      CLKOUT5_PHASE => 0.0,
      CLK_FEEDBACK => "CLKFBOUT",         
      COMPENSATION => "SYSTEM_SYNCHRONOUS",
      DIVCLK_DIVIDE => 1,                 
      REF_JITTER => 0.1,                 
      RESET_ON_LOSS_OF_LOCK => FALSE     
   )
   port map (
      CLKFBOUT => clk_fb, -- 1-bit output: PLL_BASE feedback output
      CLKOUT0 => pll_clkout0,
      CLKOUT1 => pll_clkout1,
      CLKOUT2 => open,
      CLKOUT3 => open,
      CLKOUT4 => open,
      CLKOUT5 => open,
      LOCKED => locked,     -- 1-bit output: PLL_BASE lock status output
      CLKFBIN => clk_fb,   -- 1-bit input: Feedback clock input
      CLKIN => clkin,       -- 1-bit input: Clock input
      RST => reset            -- 1-bit input: Reset input
   ); 
 
  u_BUFG0  : BUFG PORT MAP (I => pll_clkout0, O => clkbufout0);
  u_BUFG1  : BUFG PORT MAP (I => pll_clkout1, O => clkbufout1);
  
  n_clkbufout0  <= NOT clkbufout0;
  n_clkbufout1  <= NOT clkbufout1;
 
  u_ODDR2_0 : ODDR2
   generic map(
      DDR_ALIGNMENT => "NONE", -- Sets output alignment to "NONE", "C0", "C1"
      INIT => '0', -- Sets initial state of the Q output to '0' or '1'
      SRTYPE => "SYNC") -- Specifies "SYNC" or "ASYNC" set/reset
   port map (
      Q  => oddr2out0, -- 1-bit output data
      C0 => clkbufout0, -- 1-bit clock input
      C1 => n_clkbufout0, -- 1-bit clock input
      CE => '1',  -- 1-bit clock enable input
      D0 => '1',   -- 1-bit data input (associated with C0)
      D1 => '0',   -- 1-bit data input (associated with C1)
      R  => reset,    -- 1-bit reset input
      S  => '0'     -- 1-bit set input
   );
 
 u_ODDR2_1 : ODDR2
   generic map(
      DDR_ALIGNMENT => "NONE", -- Sets output alignment to "NONE", "C0", "C1"
      INIT => '0', -- Sets initial state of the Q output to '0' or '1'
      SRTYPE => "SYNC") -- Specifies "SYNC" or "ASYNC" set/reset
   port map (
      Q  => oddr2out1, -- 1-bit output data
      C0 => clkbufout1, -- 1-bit clock input
      C1 => n_clkbufout1, -- 1-bit clock input
      CE => '1',  -- 1-bit clock enable input
      D0 => '1',   -- 1-bit data input (associated with C0)
      D1 => '0',   -- 1-bit data input (associated with C1)
      R  => reset,    -- 1-bit reset input
      S  => '0'     -- 1-bit set input
   );

  u_OBUF0 : OBUF PORT MAP (I => oddr2out0, O => pll_out0);
  u_OBUF1 : OBUF PORT MAP (I => oddr2out1, O => pll_out1);
end Behavioral;

注意最後是接OBUF,不可以接BUFG,不然會有ERROR : PACK 2530 ::The dual data rate register "u_ODDR2_0 " failed to join an OLOGIC component as required.

如果是differential outputs則改成如下,我覺得很奇怪為什麼手冊裡面沒有詳細的OBUFDS,
我是再Spartan3 裡面找到pinout的

OBUFDS_0 : OBUFDS
  port map (
  O => pll_out0_p, -- Diff_p output (connect to top-level port)
  OB => pll_out0_n, -- Diff_n output (connect to top-level port)
  I => oddr2out0 -- Buffer input
  );
 
  OBUFDS_1 : OBUFDS
  port map (
  O => pll_out1_p, -- Diff_p output (connect to top-level port)
  OB => pll_out1_n, -- Diff_n output (connect to top-level port)
  I => oddr2out1 -- Buffer input
  );