特電ラッパの詳細
1.特電ラッパの詳細
特電ラッパは、IPコア本体(ネットリスト)と、CoreGenの生成したラッパを接続します。CoreGenの生成物は、TLPベースの難解な入出力ポートを持ちますが、それをIPコア本体に橋渡しし、また、特電IPコアからの信号をユーザインタフェースに受け渡します。
図1 特電ラッパの役割
2.入出力ポートの説明
2.1 シンボル
特電ラッパの入出力ポートのシンボルを図2に示します。本ラッパの入出力信号は、システム用ポート、PCIe用ポート、設定ポート、ユーザ回路用インタフェース用信号、DMA用ポート、割り込み信号ポート、その他の8種類に分けられます。
図2 特電ラッパの入出力ポート(バージョン0.9仕様)
※ gpio_out[31:0]、gpio_in[31:0]、sw_i[7:0]、cfg_clk_o、cfg_cs_o、cfg_mosi_o、cfg_miso_i、cfg_busy_o、xio_diag_oの各ポートは削除されました。これらのポートは、従来のバージョンでも何ら意味を持ちませんでした。
2.2 システム用ポート
システム用のポートをリスト1に示します。
pclk_o : out std_logic; reset_o : out std_logic; |
特電ラッパには、汎用のクロック入力や、リセット入力はありません。
これらの信号はPCI Expressのレーンを通じて受け取るためです。
特電ラッパにはクロック出力とリセット出力のみ存在します。
pclk_oは125MHzのクロック出力、reset_oはPCI Expressをデコードして得られたリセット出力です。
これらの信号は、PCI Expressでホストに接続されていないときには正しく出力されないので、ご注意ください。
2.3 設定ポート
custoimize_cとkeycode_cは、ユーザカスタマイズ用の入力ポートです。これらのポートには必ず固定値を与えるようにしてください。付属のサンプルデザインでは、main.vhdの中で定数として設定しています。
customize_c : in std_logic_vector(259 downto 0); keycode_c : in std_logic_vector(47 downto 0); |
custoimize_cは特電ラッパでは使用されません。将来のバージョンでは削除または縮小される予定です。
keycode_cはIPコアを有効にするためのコードです。弊社から指定された値を代入してください。この値が正しく設定されない場合は、起動後60分で動作を停止します。
2.4 ユーザ回路用ローカルポート
ユーザ回路用ローカルポートは、ユーザ用のポートです。
メモリ書き込み要求とメモリ読み出し要求をベースにした非常にシンプルなインタフェースです。
-- ユーザ回路インタフェース用 user_addr_o : out std_logic_vector(31 downto 0); user_length_o : out std_logic_vector(31 downto 0); user_wdata_o : out std_logic_vector(31 downto 0); user_be_o : out std_logic_vector(3 downto 0); user_dvalid_o : out std_logic; user_dreq_o : out std_logic;
-- BAR0 is used for control bar0_wrreq_o : out std_logic; bar0_rdreq_o : out std_logic; bar0_rdack_i : in std_logic; bar0_rdata_i : in std_logic_vector(31 downto 0);
-- BAR1 is used for memory bar1_wrreq_o : out std_logic; bar1_rdreq_o : out std_logic; bar1_rdack_i : in std_logic; bar1_rdata_i : in std_logic_vector(31 downto 0);
-- BAR2 is used for memory bar2_wrreq_o : out std_logic; bar2_rdreq_o : out std_logic; bar2_rdack_i : in std_logic; bar2_rdata_i : in std_logic_vector(31 downto 0);
-- BARR is used for EXPANSION ROM bar2_wrreq_o : out std_logic; bar2_rdreq_o : out std_logic; bar2_rdack_i : in std_logic; bar2_rdata_i : in std_logic_vector(31 downto 0);
|
各信号の機能と使用方法を以下に示します。
表1 ユーザ用ローカルポートの信号
信号名 |
方向 |
機能 |
user_addr_o[31:0] |
出力 | メモリ/IOアクセスの際に、ホストPCから与えられたアドレスが出力されます。 |
user_length_o[31:0] |
出力 | メモリ/IOアクセスの際に、ホストPCから与えられた長さ(DW単位)が出力されます。 |
user_wdata_o[31:0] |
出力 | メモリ/IOライト・アクセスの際に、ホストPCから与えられたデータが出力されます。 |
user_be_o[3:0] |
出力 | メモリ/IOアクセスの際に、どのバイトがイネーブルになっているかを示します。 |
user_dvalid_o |
出力 |
user_wdata_oに有効なデータが出力されていることを示します。 |
user_dreq_o |
出力 |
コアがデータを要求しているタイミングを示します。 |
bar*_wrreq_o |
出力 | BAR*がライト動作をリクエストしていることを示します。 |
bar*_rdreq_o |
出力 | BAR*がリード動作をリクエストしていることを示します。 |
bar*_rdack_i |
入力 | ユーザ回路が有効なデータが用意できたことをコアに示します。 |
bar*_rdata_i[31:0] |
入力 | ユーザ回路からコアに与えるデータです。 |
2.5 PCIeエッジ用ポート/PCIeケーブル用ポート
以下の信号は、PCI Expressの信号です。高速差動シリアル信号と、クロック、低速信号(リセット、WAKE)を含みます。
-- ケーブル用 GTP Port cpcie_txp_op : out std_logic; cpcie_txn_op : out std_logic; cpcie_rxp_ip : in std_logic; cpcie_rxn_ip : in std_logic; cpcie_refclkp_ip : in std_logic; cpcie_refclkn_ip : in std_logic; cpcie_perst_ip : in std_logic; cpcie_wake_op : out std_logic;
-- ケーブル用 GTP Port epcie_txp_op : out std_logic; epcie_txn_op : out std_logic; epcie_rxp_ip : in std_logic; epcie_rxn_ip : in std_logic; epcie_refclkp_ip : in std_logic; epcie_refclkn_ip : in std_logic; epcie_perst_ip : in std_logic; epcie_wake_op : out std_logic; |
これらの信号は、間に回路を挟まず、直接FPGAの外へ取り出してください。
表2 PCI Expressレーン用の信号
信号名 |
方向 |
機能 |
cpcie_txp_op |
出力 | External Cabling用の高速シリアル送信信号です |
cpcie_txn_op |
入力 | External Cabling用の高速シリアル送信信号です |
cpcie_rxp_ip |
入力 | External Cabling用の高速シリアル受信信号です |
cpcie_rxn_ip |
入力 | External Cabling用の高速シリアル受信信号です |
cpcie_refclkp_ip |
入力 | External Cabling用の差動クロック入力です |
cpcie_refclkn_ip |
入力 |
External Cabling用の差動クロック入力です |
cpcie_perst_ip |
入力 | External Cabling用のリセット入力です(正論理) |
cpcie_wake_op |
出力 | External Cabling用のWakeup出力です |
epcie_txp_op |
出力 | カードエッジ用の高速シリアル送信信号です |
epcie_txn_op |
出力 | カードエッジ用の高速シリアル送信信号です |
epcie_rxp_ip |
入力 | カードエッジ用の高速シリアル受信信号です |
epcie_rxn_ip |
入力 | カードエッジ用の高速シリアル受信信号です |
epcie_refclkp_ip |
入力 | カードエッジ用の差動クロック入力です |
epcie_refclkn_ip |
入力 | カードエッジ用の差動クロック入力です |
epcie_perst_ip |
入力 | カードエッジ用のリセット入力です(負論理) |
epcie_wake_op |
出力 | カードエッジ用のWakeup出力です |
External Cable用ポートとカードエッジ用ポートは排他的に使用されます。
どちらのポートが使われるかは、ラッパに与えるGeneric文で設定します。
Generic (
USE_PCIE_CABLE : boolean := FALSE
);
この値をFALSE(デフォルト)にするとカードエッジ側が使用されます。TRUEにするとExternal Cablingが使用されます。External Cablingを使用する場合は、CoreGenをカスタマイズして、GTPのトランシーバにX0Y0のChannel0が使用されるようにしてください。
2.6 割り込み用ポート
以下の信号は、割り込み発生のためのポートです。
-- Interrupt control port int_reqline_i : in std_logic; int_available_o : out std_logic; int_ack_o : out std_logic;
|
表3 割り込み用ポート
信号名 |
方向 |
機能 |
int_reqline_i |
入力 | 割り込みラインの値を指定します |
int_available_o |
出力 |
割り込みが使用可能であることを示します。 |
int_ack_o |
出力 |
割り込みラインの遷移が受け入れられたことを示します |
割り込みラインというのは、PCIの割り込みラインをエミュレートしたものです。この信号を遷移させると、Messageパケットが送出され、ホストPCに割り込みラインの遷移が通知されます。
このラインが0になると、ホストPC内の仮想的な割り込みラインがLレベルになり、割り込みが要求されます。
しかしながら、int_reqline_iを遷移させるだけでは、システムに割り込みをかけて意味のある動作をさせることはできません。意味のある割り込みを実現するためには、割り込みコントロールレジスタを別途実装する必要があります。特電コアのdmaint_user.ngcには、割り込みコントロールレジスタの実装例があります。
2.7 DMA用ポート
以下の信号は、DMAのためのポートです。
-- DMA control port dma_cfg_c : in std_logic_vector(15 downto 0); dma_sysaddr_i : in std_logic_vector(31 downto 0); -- PC内メインメモリの物理アドレス dma_lcladdr_i : in std_logic_vector(31 downto 0); -- ローカル(コア上)のアドレス dma_length_i : in std_logic_vector(9 downto 0); -- DW単位 dma_wr_req_i : in std_logic; -- DMA要求(FPGA->PC) dma_wr_ack_o : out std_logic; -- DMA応答 dma_rd_req_i : in std_logic; -- DMA要求(PC->FPGA) dma_rd_ack_o : out std_logic; -- DMA応答 dma_wrdata_i : in std_logic_vector(31 downto 0); -- 書き込みデータ dma_rddata_o : out std_logic_vector(31 downto 0); -- 読み出しデータ dma_addr_o : out std_logic_vector(31 downto 0); dma_remain_o : out std_logic_vector(31 downto 0); dma_dvalid_o : out std_logic; -- DMA受信データ有効 dma_dreq_o : out std_logic; -- DMA送信データ要求 dma_corebusy_o : out std_logic; dma_userrun_i : in std_logic; dma_pktsize_o : out std_logic_vector(3 downto 0);
|
これらのポートの機能を次の表4に示します。
表4 DMA用ポート
信号名 |
方向 |
機能 |
dma_cfg_c[15:0] |
入力 |
DMAの設定に用いられるポートです。現在のバージョンでは使用されていません。x"0000"を与えてください |
dma_sysaddr_i[31:0] |
入力 |
DMA転送を開始するホストPC上のメモリアドレス(論理アドレス)を指定します。 |
dma_lcladdr_i[31:0] |
入力 |
DMA転送を開始するコア上のローカルアドレスを指定します。 |
dma_length_i[9:0] |
入力 | DMA転送を行う長さ(DW単位)を指定します。 |
dma_wr_req_i |
入力 | ホストPCに対してDMAライト(FPGA→PC方向)を要求します |
dma_wr_ack_o |
出力 | DMAライト要求が受け付けられ、TLPが送出されたことを示します。 |
dma_rd_req_i |
入力 |
ホストPCに対してDMAリード(PC→FPGA方向)を要求します |
dma_rd_ack_o |
出力 | DMA要求が受け付けられ、TLPが送出されたことを示します。 |
dma_wrdata_i[31:0] |
入力 | DMA転送で送信するデータを入力します |
dma_rddata_o[31:0] |
出力 | DMA転送で受信したデータが出力されます |
dma_addr_o[31:0] |
出力 | DMA転送を行っている際のローカルアドレスが出力されます |
dma_remain_o[31:0] |
出力 | 現在は使用されていません。 |
dma_dvalid_o |
出力 |
DMAリードの際に、dma_rddata_o[31:0]ポートに出力している受信データが有効であることを示します。 |
dma_dreq_o |
出力 |
DMAライトの際に、コアが、dma_wrdata_i[31:0]にデータを要求していることを示します。 |
dma_corebusy_o |
出力 | DMA用のTLPが送信中であることを示します |
dma_userrun_i |
入力 | 上位のDMAコントロールステートマシンが動作中であることを示します。受信したコンプリーションパケットのデコードに用いられます。 |
dma_pktsize_o |
出力 | 現在は使用されていません |
本コアは、1つのTLPを送信する機能を持ちます。
dma_sysaddr_iにホストPC上のアドレスを設定し、dma_length_iに長さを指定し、dma_lcladdr_iにローカルアドレスを設定して、dma_wr_req_iまたはdma_rd_req_iを'1'にすることで、DMAが実行されます。
DMAライトを行う場合、dma_wr_req_iをアサートした後、dma_dreq_oが'1'になったタイミングでdma_wrdata_i[31:0]にデータを与えます。
DMAリードを行う場合、dma_rd_req_iをアサートした後、しばらくすると、ホストPCがコンプリーションを返してくるので、コアはそれをデコードしてdma_rddata_o[31:0]に出力します。データが出力されるタイミングで、dma_dvalid_oが'1'になるので、ユーザ回路はそれを取り込みます。
dma_sysaddr_i[31:0]にはホストPC上の論理アドレスを指定します。このアドレスを誤って設定してDMAライトを行うと、ホストPC上のメモリを破壊します。ご注意ください。
※論理アドレスは物理アドレスとほぼ同じ意味ですが、完全に同じではありません。最近のPCでは物理アドレスは使用しません。
dma_lcladdr_i[31:0]には、DMAを行う際のローカルアドレス(FPGA内のローカルアドレス)を指定します。これは、例えばDDR2メモリのアドレスの指定などに用います。
dma_addr_o[31:0]は、現在DMA転送を行っているアドレスが出力されます。最初はdma_lcladdr_iと同じアドレスが出力され、以後、1ワード転送するたびに4つずつインクリメントしていきます。メモリ等を接続する場合にこのポートを使います。
本コアのDMAコントローラは、1つのTLPを送信するだけの機能しかありません。ホストPCのどこのアドレスに対してDMAを送信すればよいかといった情報や、大きなサイズのDMAを最大ペイロードサイズ以下のサイズに細切れにして複数のDMAパケットを送信するといった機能はありません。したがって、本コアだけでは、DMAは4096バイト以下のサイズの転送しか行うことができません。
より実用的なDMAを行うためには、上位のDMAコントローラと、DMAコントロール・レジスタを実装する必要があります。また、DMAの完了したタイミングを知るため割り込みの実装も不可欠です。
特電コアのdmaint_user.ngcには、DMAコントローラと、割り込みコントロールレジスタの実装例があります。
3.動作波形
メモリ・ライト・リクエスト
ホストPCからBAR0〜BAR2またはBARR空間への書き込み要求が発行され、PCIeコアがTLPを受け取ると、bar*_wr_oがアサートされます。
そのとき、ホストPCからリクエストされたアドレスと、操作長、データが、user_addr_o、user_length_o、user_wdata_oからそれぞれ出力されます。(user_addr,length,wdataは各BAR共通で使われます)
書き込みデータは、user_wdata_oから出力されます。すべてのBARで、このポートが使用されます。書き込みデータが有効になるとuser_dvalid_o信号がアサートされ、バイトイネーブル信号がuser_be_o[3:0]に出力されます。
これらの信号はコア内でバッファリングされませんので、ユーザアプリケーションで必ず受け取ってください。書き込み操作の例として、図4に、パソコンから0xFDFBC000番地(物理アドレス)に、16バイトのデータを連続して書き込み要求した場合の例を示します。図3の波形では、32bitのデータを4回受け取っています。
※ bar0_wr_oは、実際にメモリ書き込みアクセスが起こるタイミングではなく、BAR0空間にメモリ書き込みが起こることを予告するために用いられます。実際の書き込みにはuser_dvalid_o信号を使用してください。bar0_wr_oは、アドレス、BE、LENGTHはuser_dvalid_o信号よりも1クロック早く出力されます。 |
図3 メモリ・ライト・リクエスト受信時(パソコン方向→アドインカードへのメモリ転送)
メモリ・リード・リクエスト
ホストPCからBAR0〜BAR2空間への読み出し要求が発行されると、bar*_rdreq_oがアサートされます。そのとき、リクエストれたアドレスと操作長がuser_addr_oとuser_length_oに出力されます。また、バイトイネーブル信号がBE[3:0]に出力されます。ユーザアプリケーションは、データの準備ができたらbar*_rdackをアサートしてください。アサートしないとパソコンは待ち続けてしまい動作速度が低下します。
その後、コアがbar*_dreq信号をHレベルにしたタイミングで、bar*_rdata_iバスからデータが取り込まれます。コアが出力するアドレスと長さは自動的に更新されます。
この操作の波形例を図5に示します。これは、パソコンが0xFDFBC000番地(物理アドレス)から、8バイトのデータをバースト転送で読み出そうとしている場合の波形です。図4の波形では、32bitのデータを2回送っています。
図4 メモリ・ライト・リクエスト受信時(パソコン方向→アドインカードへのメモリ転送)
※ bar0_rd_oは、実際にメモリ読み出しアクセスが起こるタイミングではなく、BAR0空間にメモリ読み出しが起こることを予告するために用いられます。実際の読み出しは、user_dreq_oのタイミングで行われます。 |
Copyright(C) 2009 TokushuDenshiKairo Inc. All rights reserved.