UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

AR# 55479

CPRI v6.1、7 シリーズ - プロダクション GTP トランシーバーのリセット ロジックに必要な GT アップデートと GTP/GTX および GTH トランシーバーでの TX バッファーのバイパス

説明

CPRI コアのバージョン 6.1 は、最新のトランシーバー設定でリリースされていますが、Artix-7 FPGA のデザイン アドバイザリのマスター アンサー (ザイリンクス アンサー 51456) に説明されているすべてのアップデートが適用されていることを確認してください。

ソリューション

TX 同期コントローラーの変更

(ザイリンクス アンサー 55009) に、CPRI コアのバージョン 6.1 にはない位相アライメントのインプリメンテーションに必要な変更が説明されています。このため、GTP トランシーバーを使用するデザインでは、次の手順に従います。

手順 1

CORE Generator ツールにある 7 Series FPGAs Transceivers Wizard のバージョン 2.5 を開き、プロトコル テンプレートを CPRI に設定してコアを生成します。生成したら、gtwizard_v2_5_tx_manual_phase_align.vhd ファイルを gtwizard_v2_5/example_design ディレクトリから CPRI コアの example_design/gtp_and_clocks/gtp ディレクトリにコピーします。 このファイルとファイル内にあるエンティティとアーキテクチャの名前を <component_name>_tx_sync.vhd に変更します。 gtwizard_v2_5_sync_block.vhd ファイルと gtwizard_v2_5_sync_pulse ファイルをコピーし、ISE プロジェクトまたはインプリメンテーションおよびシミュレーション スクリプト ファイルに追加します。

手順 2

手動 TX 位相アライメント ブロックを CPRI コア ラッパー ファイルに含めます。これを実行するには、CPRI コア ファイルである example_design/gtp_and_clocks/<component_name>_gt_and_clocks.vhd に次の変更を加えます。

cpri_v6_1_tx_sync コンポーネントを削除し、手動 TX 位相アライメント ファイルのコンポート宣言に置き換えます。

component <component_name>_tx_sync
  Generic( NUMBER_OF_LANES          : integer range 1 to 32:= 4; 
           MASTER_LANE_ID           : integer range 0 to 31:= 0  
         );
 
    Port ( STABLE_CLOCK             : in  STD_LOGIC;             
           RESET_PHALIGNMENT        : in  STD_LOGIC;
           RUN_PHALIGNMENT          : in  STD_LOGIC;
           PHASE_ALIGNMENT_DONE     : out STD_LOGIC := '0';
           TXDLYSRESET              : out STD_LOGIC_VECTOR(NUMBER_OF_LANES-1 downto 0) := (others=> '0');
           TXDLYSRESETDONE          : in  STD_LOGIC_VECTOR(NUMBER_OF_LANES-1 downto 0);
           TXPHINIT                 : out STD_LOGIC_VECTOR(NUMBER_OF_LANES-1 downto 0) := (others=> '0');
           TXPHINITDONE             : in  STD_LOGIC_VECTOR(NUMBER_OF_LANES-1 downto 0);
           TXPHALIGN                : out STD_LOGIC_VECTOR(NUMBER_OF_LANES-1 downto 0) := (others=> '0');
           TXPHALIGNDONE            : in  STD_LOGIC_VECTOR(NUMBER_OF_LANES-1 downto 0);
           TXDLYEN                  : out STD_LOGIC_VECTOR(NUMBER_OF_LANES-1 downto 0) := (others=> '0')
           );
end component;

手順 3

位相アライメント ブロック (tx_sync_i) のインスタンシエーションも変更します。これを実行するには、<component_name>_gt_and_clocks.vhd ファイルの「TX Buffer Bypass Logic」というセクションを次のように変更します。

--------------------------- TX Buffer Bypass Logic --------------------
    -- The TX SYNC Module drives the ports needed to Bypass the TX Buffer.
    -- Include the TX SYNC module in your own design if TX Buffer is bypassed.
    txphdlyreset        <=  '0';
    txphalignen         <=  '1';
    txsyncallin         <=  txphaligndone;
    txsyncin            <=  txsyncout;
    txsyncmode          <=  '1';
  
   
    tx_sync_i : <component_name>_tx_sync
    generic map
    ( NUMBER_OF_LANES        =>  1,
      MASTER_LANE_ID       =>  0
    )
    port map
    (
        STABLE_CLOCK                    =>      aux_clk,
        RESET_PHALIGNMENT               =>      reset_phalignment,
        RUN_PHALIGNMENT                 =>      '1',
        PHASE_ALIGNMENT_DONE            =>      phase_alignment_done,
        TXDLYSRESET                     =>      txdlysreset_vec,
        TXDLYSRESETDONE                 =>      txdlysresetdone_vec,
        TXPHINIT                        =>      txphinit_vec,
        TXPHINITDONE                    =>      txphinitdone_vec,
        TXPHALIGN                       =>      txphalign_vec,
        TXPHALIGNDONE                   =>      txphaligndone_vec,
        TXDLYEN                         =>      txdlyen_vec
    );
  
   txdlysreset            <= txdlysreset_vec(0);
   txdlysresetdone_vec(0) <= txdlysresetdone;
   txphinit               <= txphinit_vec(0);
   txphalign              <= txphalign_vec(0);
   txphaligndone_vec(0)   <= txphaligndone;
   txdlyen                <= txdlyen_vec(0);
   txphinitdone_vec(0)    <= txphinitdone;
  
   reset_phalignment <= not (tx_clk_ok and txresetdone);

変更は、RX Buffer Bypass Logic で始まるセクションで終了です。

手順 4

ファイルで次の信号を宣言します。

  signal txdlysreset_vec          : std_logic_vector(0 downto 0);
  signal txdlysresetdone_vec      : std_logic_vector(0 downto 0);
  signal txphinit_vec             : std_logic_vector(0 downto 0);
  signal txphinitdone_vec         : std_logic_vector(0 downto 0);
  signal txphalign_vec            : std_logic_vector(0 downto 0);
  signal txphaligndone_vec        : std_logic_vector(0 downto 0);
  signal txdlyen_vec              : std_logic_vector(0 downto 0);
  signal phase_alignment_done     : std_logic;
  signal reset_phalignment        : std_logic;

手順 5

このファイルで位相アライメント ブロックの DONE 出力を tx_sync_rst signal の生成に追加します。

tx_sync_rst <= not (tx_clk_ok and txresetdone and phase_alignment_done);

手順 6

TXSYNC_OVRD トランシーバー パラメーターを 1 に設定して (ザイリンクス アンサー 55009) の変更を完了します。これは example_design/gtp_and_clocks/gtp/<component_name>_v7_gtwizard.vhd ファイルで設定します。

TXSYNC_OVRD_IN         => ('1'),


RX リセット シーケンスの変更

(ザイリンクス アンサー 53561) に、GTP トランシーバーを使用するデザインのレシーバー リセット プロセスの変更が説明されています。この変更は、CPRI コアのバージョン 6.1 にはありません。2013 年 1 月にリリースされた CPRI コアのバージョン 7.0 にアップグレードすることをお勧めします。
バージョン 7.0 にアップグレードできない場合は、次の手順で説明されているステート マシンを example_design/gtp_and_clocks/<component_name>_gt_and_clocks.vhd ファイルに追加すると、必要な変更をバージョン 6.1 の GTP デザインに追加できます。

手順 1

example_design/gtp_and_clocks/<component_name>_gt_and_clocks.vhd ファイルで次の行を見つけます。

  gtxtxreset <= (rst_count_done and (reset or gt_reset_req or not(rxplllkdet))) or watchdog_reset;
  gtxrxreset <= (rst_count_done and (reset or gt_reset_req or not(rxplllkdet))) or watchdog_reset;

これを次のコードに置き換えます。

  gtxtxreset <= (rst_count_done and (reset or gt_reset_req_i or not(rxplllkdet))) or watchdog_reset;
  gtxrxreset_i <= (rst_count_done and (reset or gt_reset_req_i or not(rxplllkdet))) or watchdog_reset;
 
  -- Synchronize reset signal to state machine clock
  rx_sync_reset_sync_rsm_i : <component_name>_reset_synchronizer
  port map (
    reset_in  => gtxrxreset_i,
    clk       => aux_clk,
    reset_out => gtxrxreset_r
    );
   
  -- Synchronize the rxpmaresetdone signal into the state machine clock
  -- domain
  rxpmaresetdone_sync_rsm_i : <component_name>_synchronizer
  port map (
      q     => rxpmaresetdone_r,
      clk   => aux_clk,
      reset => reset,
      d     => rxpmaresetdone);
 
  -- State machine to perform internal data width change in response to
  -- a user reset
  reset_change_sm : process(aux_clk)
  begin
    if rising_edge(aux_clk) then
      if (reset = '1') then
        reset_sm_state <= idle;
      else
        case reset_sm_state is
          when idle =>
            gtxrxreset    <= '0';
            reset_sm_busy <= '0';
            reset_daddr(7 downto 0) <= (others => '0');
            reset_den               <= '0';
            reset_dwe               <= '0';
            reset_di                <= (others => '0');
            if (gtxrxreset_r = '1') then
              reset_sm_state <= wait_for_speed_sm;
            end if;
          when wait_for_speed_sm =>
            if (sm_busy = '0') then
              reset_sm_state <= read_11;
              reset_sm_busy <= '1';
            end if;
          when read_11 =>
            gtxrxreset    <= '1';
            reset_daddr(7 downto 0) <= x"11";
            reset_den        <= '1';
            reset_dwe        <= '0';
            reset_sm_state <= wait_for_11r_rdy;
          when wait_for_11r_rdy =>
            reset_den        <= '0';
            reset_dwe        <= '0';
            if (gt_drdy_channel = '1') then
              reset_rdata <= gt_do_channel;
              reset_sm_state <= write_11;
            end if;
          when write_11 =>
            reset_den        <= '1';
            reset_dwe        <= '1';
            -- 11 holds RX_DATA_WIDTH
            reset_di <= gt_do_channel(15 downto 14) & "010" & gt_do_channel(10 downto 0);
            reset_sm_state <= wait_for_11_rdy;
          when wait_for_11_rdy =>
            reset_den        <= '0';
            reset_dwe        <= '0';
            if (gt_drdy_channel = '1') then
              reset_sm_state <= wait_for_gtxrxreset_i_low;
            end if;
          when wait_for_gtxrxreset_i_low =>
            reset_den        <= '0';
            reset_dwe        <= '0';
            if (gtxrxreset_r = '0') then
              gtxrxreset <= '0';
              reset_sm_state <= wait_for_pmaresetdone_high;
            end if;
          when wait_for_pmaresetdone_high =>
            reset_den        <= '0';
            reset_dwe        <= '0';
            if (rxpmaresetdone_r = '1') then
              reset_sm_state <= wait_for_pmaresetdone_low;
            end if;
          when wait_for_pmaresetdone_low =>
            reset_den        <= '0';
            reset_dwe        <= '0';
            if (rxpmaresetdone_r = '0') then
              reset_sm_state <= read_11_2;
            end if;
          when read_11_2 =>
            reset_daddr(7 downto 0) <= x"11";
            reset_den        <= '1';
            reset_dwe        <= '0';
            reset_sm_state <= wait_for_11r_rdy_2;
          when wait_for_11r_rdy_2 =>
            reset_den        <= '0';
            reset_dwe        <= '0';
            if (gt_drdy_channel = '1') then
              reset_rdata <= gt_do_channel;
              reset_sm_state <= write_11_2;
            end if;
          when write_11_2 =>
            reset_den        <= '1';
            reset_dwe        <= '1';
            -- 11 holds RX_DATA_WIDTH
            reset_di <= gt_do_channel(15 downto 14) & "011" & gt_do_channel(10 downto 0);
            reset_sm_state <= wait_for_11_rdy_2;
                   when wait_for_11_rdy_2 =>
            reset_den        <= '0';
            reset_dwe        <= '0';
            if (gt_drdy_channel = '1') then
              reset_sm_state <= idle;
            end if;
        end case;
      end if;
    end if;
  end process;
 
  -- Mux together the DRP input signals
  gt_den_channel_gtp       <= reset_den when reset_sm_busy = '1' else gt_den_channel;
  gt_dwe_channel_gtp       <= reset_dwe when reset_sm_busy = '1' else gt_dwe_channel;
  gt_di_gtp                <= reset_di when reset_sm_busy = '1' else gt_di;
  gt_daddr_gtp(7 downto 0) <= reset_daddr(7 downto 0) when reset_sm_busy = '1' else gt_daddr(7 downto 0);
  gt_daddr_gtp(8)          <= gt_daddr(8);

手順 2

ファイルで、次の信号とコンポーネントを宣言します。

  signal gtxrxreset_i           : std_logic;
  signal gtxrxreset_r           : std_logic;
  signal rxpmaresetdone         : std_logic;
  signal rxpmaresetdone_r       : std_logic;
 
  type t_state_reset is (idle, wait_for_speed_sm,
                         read_11, wait_for_11r_rdy, write_11, wait_for_11_rdy,
                         wait_for_gtxrxreset_i_low,
                         wait_for_pmaresetdone_high,
                         wait_for_pmaresetdone_low,
                         read_11_2, wait_for_11r_rdy_2, write_11_2,
                         wait_for_11_rdy_2);
 
  signal reset_sm_state     : t_state_reset := idle;
  signal reset_sm_busy      : std_logic;
  signal reset_daddr        : std_logic_vector(7 downto 0);
  signal reset_den          : std_logic;
  signal reset_dwe          : std_logic;
  signal reset_di           : std_logic_vector(15 downto 0);
  signal reset_rdata        : std_logic_vector(15 downto 0);
  signal gt_den_channel_gtp : std_logic;
  signal gt_dwe_channel_gtp : std_logic;
  signal gt_di_gtp          : std_logic_vector(15 downto 0);
  signal gt_daddr_gtp       : std_logic_vector(8 downto 0);
  signal gt_reset_req_i     : std_logic;
 
  component <component_name>_synchronizer is
    port (
      q     : out std_logic;
      clk   : in  std_logic;
      reset : in  std_logic;
      d     : in  std_logic);
  end component;

手順 3

新しいステート マシンには、トランシーバーからの RXPMARESETDONE 信号を使用する必要があります。これをトランシーバーのラッパー ファイル外に配線します。

RXPMARESETDONE 信号は、gtp_and_clocks/gtp/<component_name>_v7_gtwizard_gt.vhd ファイルのトランシーバーの出力です。これをこのファイル外に gtp_and_clocks/gtp/<component_name>_v7_gtwizard.vhd ファイルを介して配線します。 gtp_and_clocks/gtp/<component_name>_v7_gtwizard.vhd ファイルの出力が gtp_and_clocks/<component_name>_gt_and_clocks.vhd ファイル内にある rxpmaresetdone 信号に接続されます。

手順 4

ステート マシンは、リセット シーケンス中に DRP バスを使用してトランシーバーを設定します。これによってステート マシンとの間に競合が生じ、速度変更操作中にトランシーバー設定が変更されます。2 つのステート マシン間を正しくアービトレーションするには、次のように変更します。
gtp_and_clocks/<component_name>_gt_and_clocks.vhd ファイル内で speed_change_det ステート マシンを検索します。リセット ステート マシンでリセットされるように speed_select_r 信号を変更します。

  -- Small state machine to set the RXCDR_CFG setting in the transceiver
  -- This depends on the line rate that the link is operating at.
  -- Firstly detect a speed change.
  speed_change_det : process(aux_clk)
  begin
    if rising_edge(aux_clk) then
      if reset_sm_busy = '0' then - Reset changed
        speed_select_r <= speed_select;
      end if;
    end if;
  end process speed_change_det;

手順 5

speed_change_sm ステート マシンを、新しいリセット ステート マシンがビジーになったときにリセットされるように変更します。speed_change_sm process を検索し、次のリセットを変更します。

if (reset = '1') then

次のように変更します。

if (reset = '1' or reset_sm_busy = '1') then

手順 6

新規の gt_reset_i 信号が生成されます。gtp_and_clocks/<component_name>_gt_and_clocks.vhd ファイルに次のコードを追加します。

  gt_reset_req_sm :  process(aux_clk)
  begin
    if rising_edge(aux_clk) then
      if (reset = '1' or reset_sm_busy = '1') then
        gt_reset_req_i <= '0';
      else
        case speed_sm_state is
          when idle => gt_reset_req_i <= '0';
          when wait_for_mmcm_divclk_rdy =>
            if (mmcm_drp_drdy = '1') then
              gt_reset_req_i <= '1';
            end if;
          when others =>
            gt_reset_req_i <= '0';
        end case;
      end if;
    end if;
  end process;

手順 7

2 つのステート マシンからのマルチプレクサーを介する出力信号をトランシーバーのラッパーに配線します。ファイルの Channel Dynamic Reconfiguration Port (DRP) で始まるセクションを、次のように変更します。

        ---------------- Channel - Dynamic Reconfiguration Port (DRP) --------------
        GT0_DRPADDR_IN                  =>      gt_daddr_gtp,
        GT0_DRPCLK_IN                   =>      aux_clk,
        GT0_DRPDI_IN                    =>      gt_di_gtp,
        GT0_DRPDO_OUT                   =>      gt_do_channel,
        GT0_DRPEN_IN                    =>      gt_den_channel_gtp,
        GT0_DRPRDY_OUT                  =>      gt_drdy_channel,
        GT0_DRPWE_IN                    =>      gt_dwe_channel_gtp,

手順 8

このファイルへの変更を完了するには、新規ステート マシンの BUSY 出力を CDR ロック カウンター、drp_arb_gnt および gt_daddr 信号の生成に配線します。

   --------------------------- RX Buffer Bypass Logic --------------------
   -- The RX SYNC Module drives the ports needed to Bypass the RX Buffer.
   -- Include the RX SYNC module in your own design if RX Buffer is bypassed.
   --Wait till CDR is locked to start RX Phase Alignment
 
   RX_CDRLOCK_TIME    <=   "00010000000000" when (WRAPPER_SIM_GTXRESET_SPEEDUP = 1)  else  "10011100010000";
 
   process( aux_clk, reset_sm_busy, gtxrxreset)
   begin
       if(gtxrxreset = '1' or reset_sm_busy = '1' ) then
           rx_cdrlock_counter    <=  (others => '0');
 
       elsif(aux_clk'event and aux_clk = '1') then
           if(rx_cdrlock_counter <= RX_CDRLOCK_TIME)  then
              rx_cdrlock_counter    <= rx_cdrlock_counter + 1;
           else
              rx_cdrlock_counter    <= rx_cdrlock_counter;
           end if;
       end if;
   end process;
 
  -- Send a grant back to the core when the DRP is ready
  drp_arb_gnt <= drp_arb_req and not(sm_busy) and not(reset_sm_busy);
 
  -- Set top bit of DRP address high when we're accessing the barrel shift
  gt_daddr(8) <= '1' when (gt_drp_daddr(7 downto 0) = x"50"
                           and sm_busy = '0' and reset_sm_busy = '0') else '0';

手順 9

example_design/gtx_and_clocks/<component_name>_watchdog.vhd ファイルで CPRI ウォッチドッグ タイマーのタイムアウトを増加させます。 リセット シーケンスが長くなっているので、低ライン速度では完了前にタイムアウトする可能性があります。

現在のコードでは、125MHz の補助クロックを使用してウォッチドッグ タイマーを駆動すると想定されています。タイマーは 20 ビットのカウンターで、約 4ms 後にタイムアウトします。カウンターを 24 ビットに増加し、64 ms でタイムアウトするようにすることが推奨されます。これには、WDOG_COUNT_SIZE 定数を 24 に変更します。

手順 10

GTP ベースのコアの場合、上記の変更のほかに、次の属性を正しく設定する必要があります。

PMA_RSV2 =x00002040 (GTP チャネル)
BIAS_CFG =x"0000000000050001" (GTP 共通)

修正したデザインを正しくシミュレーションするためには、SIM_GTRESET_SPEEDUP パラメーターを false に設定する必要があります。

AR# 55479
日付 04/30/2013
ステータス アーカイブ
種類 一般
デバイス
IP
このページをブックマークに追加