IPコアの使い方(但し、Version 0.5用)
1.はじめに
このIPコアは、PCI Expressの膨大な仕様のうち、通信の確立に必要な最低限の機能のみを実装したものです。したがって、規格に準拠してはいませんが、FPGAの論理合成時間が短く(約2分)、リソース使用量も非常に少ないという利点があります。現時点ではBlockRAMも使用しておりません。
したがって、特定の環境でのみ通信ができればよいとするような、研究機器やカスタム製品の開発用に適しています。
このコアは、現時点では、パソコンからアクセスできる汎用GPIOの機能(PIOモード)として提供されています。コアのVersion0.5以降では、バースト転送にも対応しています。
本IPコアの入出力信号はPIPE用にデザインされています。PIPE信号をTexasInstruments社のPHYに適合させ、かつ、XILINX社のFPGAに実装するため、付録のサンプルデザインではコアの上にラッパー(xiosmpl.vhd)を被せています。(図1)
ラッパー内には、ODDRやDCMなどXILINX FPGA専用のプリミティブが含まれます。
通常の用途では、ラッパをカスタマイズする必要はありません。
図1 特電IPコアとラッパ、ユーザロジックの関係
2.IPコアの機能
2.1 シンボル
本IPコアのシンボルを図2に示します。本IPコアの入出力信号は、システム用ポート、設定ポート、シリアルメモリ用ポート、ユーザ回路用インタフェース用信号、DMA用ポートの4種類に分けられます。
図2 特電IPコアのシンボル(クリックで拡大)
2.2 システム用ポート
システム用のポートをリスト1に示します。
リスト1 システム用ポート |
CLK125M : in std_logic; RESET_I : in std_logic; LTSTATE_O : out std_logic_vector(4 downto 0); -- PIPEインタフェース用 pipe_rx_status_ip : in std_logic_vector(2 downto 0); pipe_rx_elecidle_ip : in std_logic; pipe_rx_valid_ip : in std_logic; pipe_phy_status_ip : in std_logic; pipe_rx_polarity_op : out std_logic; pipe_tx_compliance_op : out std_logic; pipe_powerdown_op : out std_logic_vector(1 downto 0); pipe_tx_elecidle_op : out std_logic; pipe_tx_det_loopback_op : out std_logic;
RXDATA_I : in std_logic_vector(15 downto 0); RXDATAK_I : in std_logic_vector(1 downto 0); TXDATA_O : out std_logic_vector(15 downto 0); TXDATAK_O : out std_logic_vector(1 downto 0);
DEBUG : out std_logic_vector(15 downto 0) |
CLK125MとRESET_Iはクロックとリセットです。これらの信号はラッパ内で生成されます。
LTSTATE_OとDEBUGは、デバッグ用です。
pipe_で始まる名前のポートはすべてPIPE用のポートです。これらの信号はPHYチップへ接続してください。
RXDATA_I、RXDATAK_I、TXDATA_O、TXDATAK_OもPIPE用のポートです。ビッグエンディアン(すなわち、上位のバイトが時間的に先のデータ)です。
2.3 設定ポート
custoimize_cとkeycode_cは、ユーザカスタマイズ用の入力ポートです。これらのポートには必ず固定値を与えるようにしてください。付属のサンプルデザインでは、main.vhdの中で定数として設定しています。
リスト2 設定用ポート |
customize_c : in std_logic_vector(159 downto 0); keycode_c : in std_logic_vector(47 downto 0); |
custoimize_cは128ビットのデータですが、その中にベンダIDやプロダクトIDの設定を記述します。ビットの割り当ては上のリスト2を参照してください。
keycode_cはIPコアを有効にするためのコードです。弊社から指定された値を代入してください。この値が正しく設定されない場合は、起動後60分で動作が停止します。
2.4 シリアルメモリ用ポート
シリアルメモリ用ポートは、シリアルメモリをコンフィグ空間のカスタマイズに利用できるようにするためのポートです(予定)。これらのポートはFPGAの外に出し、SPI ROMにそのまま接続してください。
リスト3 シリアルメモリ用ポート |
-- シリアルメモリ用 cfg_clk_o : out std_logic; cfg_cs_o : out std_logic; cfg_mosi_o : out std_logic; cfg_miso_i : in std_logic; cfg_busy_o : out std_logic; |
なお、コアは起動時にシリアルメモリへアクセスしますので、それを妨げないようにしてください。
2.5 ユーザ回路用ローカルポート
ユーザ回路用ローカルポートは、ユーザ用のポートです。
メモリ書き込み要求とメモリ読み出し要求をベースにした非常にシンプルなインタフェースです。
リスト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_wr_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_wr_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 DMA bar2_wr_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);
-- DMA control port dma_cfg_c : in std_logic_vector(15 downto 0); dma_wr_req_i : in std_logic; dma_rd_req_i : in std_logic; dma_wr_ack_o : out std_logic; dma_rd_ack_o : out std_logic;
|
このインタフェースの使用方法を以下に示します。
メモリ・ライト・リクエスト
パソコンからBAR0~BAR2空間への書き込み要求が発行され、PCIeコアがTLPを受け取ると、bar*_wr_oがアサートされます。
そのとき、パソコンからリクエストされたアドレスと、操作長、データが、user_addr_o、user_length_o、user_wdata_oからそれぞれ出力されます。
書き込みデータは、user_wdata_oから出力されます。すべてのBARで、このポートが使用されます。書き込みデータが有効になるとuser_dvalid_o信号がアサートされ、バイトイネーブル信号がuser_be_o[3:0]に出力されます。
これらの信号はコア内でバッファリングされませんので、ユーザアプリケーションで必ず受け取るようにしてください。
書き込み操作の例として、図4に、パソコンから0xFDFBC000番地(物理アドレス)に、16バイトのデータを連続して書き込み要求した場合の例を示します。図4の波形では、32bitのデータを4回受け取っています。
-
※ bar0_wr_oは、実際にメモリ書き込みアクセスが起こるタイミングではなく、BAR0空間にメモリ書き込みが起こることを予告するために用いられます。実際の書き込みにはuser_dvalid_o信号を使用してください。アドレス、BE、LENGTHはuser_dvalid_o信号よりも1クロック早く出力されます。
図4 メモリ・ライト・リクエスト受信時(パソコン方向→アドインカードへのメモリ転送)
メモリ・リード・リクエスト
パソコンから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バイトのデータをバースト転送で読み出そうとしている場合の波形です。図5の波形では、32bitのデータを2回送っています。
図5 メモリ・リード・リクエスト受信時(アドインカード→パソコン方向へのメモリ転送)
※ bar0_rd_oは、実際にメモリ読み出しアクセスが起こるタイミングではなく、BAR0空間にメモリ読み出しが起こることを予告するために用いられます。実際の読み出しは、user_dreq_oのタイミングで行われます。 |
3.サンプルデザイン(PCI Express GPIO)の説明
3.1 概要
付録CD-ROMの FPGA\gpio_sample フォルダに入っているものは、本IPコアを用いたGPIOのサンプルデザインです。パソコンからのメモリ・リード・ライト・リクエストによって、LEDを点滅させたりIOポートに任意のデータを出力させることができます。
また、FPGA内のBlockRAMを使用して小規模なメモリの実験が可能です。
3.2 ファイルの説明
当サンプルデザインには、下記のファイルが含まれています。
pciecore.ngc PCI Expressコア本体
xiosmpl.vhd コアをXIO1100に適合させるためのラッパ
main.vhd GPIOサンプルのメイン回路
main.ucf ピン配置およびタイミングの指定ファイル
fpga.ise WebPACK 9.1用のプロジェクトファイル
syncclk.xaw CoreGen用ファイル(DCMを用いてクロックを生成する)
cnsts.vhd 各種定数
blogana-sp3.vhdl Blogana用ソースファイル
main_summary.html 論理合成結果レポート
syncclk.vhd CoreGen用の生成したファイル
ユーザがカスタマイズ可能なのはxiosmpl.vhdとmain.vhdですが、通常はxiosmpl.vhdを変更する必要はありません。
当サンプルを論理合成する際には、ベンダIDとプロダクトIDを適当な値に設定してください。デフォルトでは両方の数値に0000が設定されているので、PCI Expressのデバイスとして認識されません。企業や研究室など閉じた環境で実験するのであればベンダIDとプロダクトIDは任意の値(たとえば誕生日とか。ただし既存のVIDと被らないように。)を設定しておけばよいでしょう。もし、作ったFPGAのデザインを第三者に提供する場合にはPCISIGからベンダIDを取得する必要があります。
ベンダIDとプロダクトIDの設定箇所は、main.vhdの85行目付近にあります。
constant customize_c : std_logic_vector(159 downto 0) :=
x"FF000000" -- [159:128] bar2 addr space (16MBytes)
& x"FFF00000" -- [127:96] bar1 addr space (1MBytes)
& x"FFFFC000" -- [95:64] bar0 addr space (16kBytes)
& x"110000" -- [63:40] class code
& x"01" -- [39:32] revision id
& x"xxxx" -- device id
& x"xxxx" ; -- vendor id
3.3 メモリマップ
当サンプルアプリケーションを実行すると、BAR0空間が256バイト、BAR1空間が65536バイト確保されます。BAR0空間はGPIO用に、BAR1空間はメモリ(BlockRAM)用に割り当てられます。
なお、GPIO空間は8192バイトのどの番地を読み書きしても、同じレジスタにアクセスされます。本サンプルでは、BAR2空間は使用されていません。
図6 サンプルアプリケーションのメモリマップ
パソコン上のソフトウェアから、(BAR0)~(BAR0)+255番地へメモリ書き込みを行うと、main.vhd内の信号(gpio_out[31:0])に書き込んだ値が出力されます。バイトマスクは行われませんので、必ず4バイト単位でアクセスしてください。
また、パソコン上のソフトウェアから、(BAR0)~(BAR0)+255番地へメモリ読み出しを行うと、gpio_in[31:0]の信号の状態が読み出されます。これも、4バイト単位でアクセスしてください。
書き込まれた値は、GPIOの出力ポートやLEDへ出力しています。
また、擬似乱数を生成してGPIO_INに接続しています。
4.IPコアの更新について
本IPコアは、開発途上のため、仕様の改正が頻繁に行われています。
これまでに行われた主な仕様の変更箇所を以下に示します。
-
-
Version0.1(一般向けリリースせず)
-
Version0.2(平成21年2月24日)
- 特定のPCで動作しない問題を解決した
-
Version0.3(平成21年3月4日)
- 基板限定コアと完全版コアの対応
-
Version0.4(平成21年3月7日)
-
user_be_o[3:0]信号を出力するようにした
-
コンフィグ空間のカスタマイズを可能にするため、c_customize定数を160ビットに変更した
-
BAR0~BAR2レジスタが正しく実装されるようにした
-
SKPパケットを送信するようにした
-
-
Version0.5(平成21年3月12日)
-
-
バースト転送に対応した。
-
リードデータを入力するためのポート(user_rdata_i)を、BARごとに分離した。
-
バースト転送に対応するため、bar*_rd_o、bar*_wr_oの扱い方を変更した。
-
バースト転送に対応するため、user_dvalid、user_dreq信号を追加した。
-
DMA用ポートを追加した。
-
各種制御信号のタイミングを厳格に定義にした
-
-