1.はじめに
PCIバスは 2002年頃から PCI Expressバスに置き換えられる様になり、近年は余り使用されなくなった様でが、製品寿命が比較的長い産業用システムでは現状でも現役です。
しかし技術テーマとしては古い為か、ネットでの情報は乏しい印象です。
例えば、PCIバス用IPをFPGAに載せてPCIバス用ターゲットデバイスを製作する際のテストベンチを簡単に作成できる様なライブラリをネットで探しても見つかりませんでした。
IPメーカさんにはあるのでしょうが、現状はサポートしていないか、有償PCI-IPの正式ユーザしかサポートされない模様です。
そこでPCIバスターゲット用テストベンチのライブラリを作成しました。
PCIバスの現状では使用する機会はそう多くはなさそうですが、皆無でもなさそうなので、機会があれば利用してみて下さい。
なお、ソースの改造等は構いませんが、本稿のオリジナルソースに関しては弊社に著作権があるものとし、ご利用の際はその旨を記載して下さい。
また結果についての責任を弊社は負えませんので、ご利用は自己責任で行なって下さい。
添付するソースファイルはASIAN記法(HDLにおける信号名称決定方法)によります。
なお、本稿はPCIバスとModelSimについての知識を有している事を前提とし、詳細説明は省きます。
2.PCIバスライブラリ使用例
PCIバスの利用者であればライブラリの使用方法は、細かい説明より使用例を見るのが最も理解と応用がし易いと思われるので、
ここでは基本的で簡単な使用例を記してユーザーズマニュアルの代替えとします。
●システム構成
図1にテストベンチのシステム構成を示します。
(クリックで拡大)
図1.テストベンチのシステム構成
●使用ファイル
ファイル名 | ファイル内容 |
---|---|
pci_master_access_2target.vht |
テストベンチ本体 ターゲットのコンフィギュレーション、SRAMのライト/リード、I/Oライト/リードを行なう。 IDSELの使用方法と機能を判り易くする為にターゲットを2つのシステムにした。 |
pci_master_access_pac.vhd |
テストベンチ用ライブラリ この中の pci_config_write 等各種サブプログラムをテストベンチ中に記述する事で、PCIバスを動かす。 |
TGT8_plus.VHD |
テストベンチ用ライブラリの動作を確認する為のターゲット用PCI-IP ユーザ用テストベンチを作成する際には本IPをユーザ使用のPCI-IPに置き換える。 以下のソースファイルを一部編集したもの Interface増刊 TECH I Vol.3 PCIデバイス設計入門 (CQ出版) 付属CDの VHDLソース ターゲット8 (バースト転送対応) TGT8.VHD 著作権者:来須川智久 氏 編集者による変更箇所は 「--px0」を付記。 主な変更は以下の通り。 @DI、DO 各8点分のI/Oレジスタ追加。 ベースアドレス +4 番地:DO[7..0] WR/RD ベースアドレス +6 番地:DI[7..0] RD ONLY A受信データのパリティチェックを追加。 パリティエラー時は PERR_n を'0'にする。 PERR_n は受信動作が終了したら自動クリアされる。 |
sram_8_model.vhd |
テストベンチ用8ビットSRMモデル SRAMのアドレス幅は RAM_ADR_WIDTH で定義するが、使用するパソコンの環境(メモリ量)によってはコンパイル時にパソコンがハングする。 pci_master_access_2target.vht では Note1 の箇所で以下の様に'10'にしているが、パソコン環境によってはさらに小さい値にしなければならないかもしれない。 constant SET_RAM_ADR_WIDTH : integer := 10; -- sram address bit |
圧縮ファイル一式 rtl_pci_test_bench.zip |
上記の全ファイル一式を一括して圧縮したもの ダウンロードして解凍すればソースファイルとして利用可能。 |
procedure pci_config_write ( set_dev_no : in integer range 0 to 31; -- --px1 set_address : in std_logic_vector(31 downto 0); -- set_ad_perr : in std_logic; -- 1: ng_parity, 0: ok_parity set_wr_data : in std_logic_vector(31 downto 0); -- set_be_n : in std_logic_vector(3 downto 0); -- set_data_perr : in std_logic; -- 1: ng_parity, 0: ok_parity ---- signal clk : in std_logic; -- signal trdy_n : in std_logic; -- signal devsel_n : in std_logic; -- signal v_idsel : out std_logic_vector(31 downto 0); -- signal frame_n : out std_logic; -- signal ad : inout std_logic_vector(31 downto 0); -- signal c_be_n : out std_logic_vector(3 downto 0); -- signal irdy_n : out std_logic; -- signal par : inout std_logic -- );
設定項目 | 設定内容 |
---|---|
set_dev_no |
integer range 0 to 31 コンフィギュレーション対象のターゲットを選択する信号線 IDSELを整数 0 〜 31で指定。 |
set_address |
std_logic_vector(31 downto 0) ライト対象のアドレスを指定。 |
set_ad_perr |
std_logic アドレスに対するパリティエラーを設定。 パリティ線 PAR を 正常パリティ(OK)にするかエラーパリティ(NG)にするかを選択する。 0:OK、 1:NG |
set_wr_data |
std_logic_vector(31 downto 0) ライトするデータを設定。 |
set_be_n |
std_logic_vector(3 downto 0) ライトデータに対する C/BE[3:0]# 信号のバイトイネーブル信号 be_n の値を設定。 |
set_data_perr |
std_logic ライトデータに対するパリティエラーを設定。 パリティ線 PAR を 正常パリティ(OK)にするかエラーパリティ(NG)にするかを選択する。 0:OK、 1:NG |
その他の信号 |
clk 以下の信号は本procedure と外部信号を接続する為のもの。 ユーザの編集禁止。 |
procedure pci_config_read ( set_dev_no : in integer range 0 to 31; -- --px1 set_address : in std_logic_vector(31 downto 0); -- set_ad_perr : in std_logic; -- 1: ng_parity, 0: ok_parity set_be_n : in std_logic_vector(3 downto 0); -- ---- signal clk : in std_logic; -- signal trdy_n : in std_logic; -- signal devsel_n : in std_logic; -- signal v_idsel : out std_logic_vector(31 downto 0); -- signal frame_n : out std_logic; -- signal ad : inout std_logic_vector(31 downto 0); -- signal c_be_n : out std_logic_vector(3 downto 0); -- signal irdy_n : out std_logic; -- signal par : inout std_logic; -- signal perr_n : out std_logic; -- signal sv_read_data : out std_logic_vector(31 downto 0) -- for test );
設定項目 | 設定内容 |
---|---|
set_dev_no |
integer range 0 to 31 コンフィギュレーション対象のターゲットを選択する信号線 IDSELを整数 0 〜 31で指定。 |
set_address |
std_logic_vector(31 downto 0) リード対象のアドレスを指定。 |
set_ad_perr |
std_logic アドレスに対するパリティエラーを設定。 パリティ線 PAR を 正常パリティ(OK)にするかエラーパリティ(NG)にするかを選択する。 0:OK、 1:NG |
set_be_n |
std_logic_vector(3 downto 0) リードデータに対する C/BE[3:0]# 信号のバイトイネーブル信号 be_n の値を設定。 |
その他の信号 |
clk 以下の信号は本procedure と外部信号を接続する為のもの。 ユーザの編集禁止。 なお、sv_read_data はリードしたデータを判り易く値として波形表示する為のものである。 |
procedure pci_memory_write ( set_address : in std_logic_vector(31 downto 0); -- set_ad_perr : in std_logic; -- 1: ng_parity, 0: ok_parity set_wr_data : in std_logic_vector(31 downto 0); -- set_be_n : in std_logic_vector(3 downto 0); -- set_data_perr : in std_logic; -- 1: ng_parity, 0: ok_parity ---- signal clk : in std_logic; -- signal trdy_n : in std_logic; -- signal devsel_n : in std_logic; -- signal frame_n : out std_logic; -- signal ad : inout std_logic_vector(31 downto 0); -- signal c_be_n : out std_logic_vector(3 downto 0); -- signal irdy_n : out std_logic; -- signal par : inout std_logic -- );
設定項目 | 設定内容 |
---|---|
set_address |
std_logic_vector(31 downto 0) ライト対象のアドレスを指定。 |
set_ad_perr |
std_logic アドレスに対するパリティエラーを設定。 パリティ線 PAR を 正常パリティ(OK)にするかエラーパリティ(NG)にするかを選択する。 0:OK、 1:NG |
set_wr_data |
std_logic_vector(31 downto 0) ライトするデータを設定。 |
set_be_n |
std_logic_vector(3 downto 0) ライトデータに対する C/BE[3:0]# 信号のバイトイネーブル信号 be_n の値を設定。 |
set_data_perr |
std_logic ライトデータに対するパリティエラーを設定。 パリティ線 PAR を 正常パリティ(OK)にするかエラーパリティ(NG)にするかを選択する。 0:OK、 1:NG |
その他の信号 |
clk 以下の信号は本procedure と外部信号を接続する為のもの。 ユーザの編集禁止。 |
procedure pci_memory_read ( set_address : in std_logic_vector(31 downto 0); -- set_ad_perr : in std_logic; -- 1: ng_parity, 0: ok_parity set_be_n : in std_logic_vector(3 downto 0); -- ---- signal clk : in std_logic; -- signal trdy_n : in std_logic; -- signal devsel_n : in std_logic; -- signal frame_n : out std_logic; -- signal ad : inout std_logic_vector(31 downto 0); -- signal c_be_n : out std_logic_vector(3 downto 0); -- signal irdy_n : out std_logic; -- signal par : inout std_logic; -- signal perr_n : out std_logic; -- signal sv_read_data : out std_logic_vector(31 downto 0) -- for test );
設定項目 | 設定内容 |
---|---|
set_address |
std_logic_vector(31 downto 0) リード対象のアドレスを指定。 |
set_ad_perr |
std_logic アドレスに対するパリティエラーを設定。 パリティ線 PAR を 正常パリティ(OK)にするかエラーパリティ(NG)にするかを選択する。 0:OK、 1:NG |
set_be_n |
std_logic_vector(3 downto 0) リードデータに対する C/BE[3:0]# 信号のバイトイネーブル信号 be_n の値を設定。 |
その他の信号 |
clk 以下の信号は本procedure と外部信号を接続する為のもの。 ユーザの編集禁止。 なお、sv_read_data はリードしたデータを判り易く値として波形表示する為のものである。 |
procedure pci_io_write ( set_address : in std_logic_vector(31 downto 0); -- set_ad_perr : in std_logic; -- 1: ng_parity, 0: ok_parity set_wr_data : in std_logic_vector(31 downto 0); -- set_be_n : in std_logic_vector(3 downto 0); -- set_data_perr : in std_logic; -- 1: ng_parity, 0: ok_parity ---- signal clk : in std_logic; -- signal trdy_n : in std_logic; -- signal devsel_n : in std_logic; -- signal frame_n : out std_logic; -- signal ad : inout std_logic_vector(31 downto 0); -- signal c_be_n : out std_logic_vector(3 downto 0); -- signal irdy_n : out std_logic; -- signal par : inout std_logic -- );
設定項目 | 設定内容 |
---|---|
set_address |
std_logic_vector(31 downto 0) ライト対象のアドレスを指定。 |
set_ad_perr |
std_logic アドレスに対するパリティエラーを設定。 パリティ線 PAR を 正常パリティ(OK)にするかエラーパリティ(NG)にするかを選択する。 0:OK、 1:NG |
set_wr_data |
std_logic_vector(31 downto 0) ライトするデータを設定。 |
set_be_n |
std_logic_vector(3 downto 0) ライトデータに対する C/BE[3:0]# 信号のバイトイネーブル信号 be_n の値を設定。 |
set_data_perr |
std_logic ライトデータに対するパリティエラーを設定。 パリティ線 PAR を 正常パリティ(OK)にするかエラーパリティ(NG)にするかを選択する。 0:OK、 1:NG |
その他の信号 |
clk 以下の信号は本procedure と外部信号を接続する為のもの。 ユーザの編集禁止。 |
procedure pci_io_read ( set_address : in std_logic_vector(31 downto 0); -- set_ad_perr : in std_logic; -- 1: ng_parity, 0: ok_parity set_be_n : in std_logic_vector(3 downto 0); -- ---- signal clk : in std_logic; -- signal trdy_n : in std_logic; -- signal devsel_n : in std_logic; -- signal frame_n : out std_logic; -- signal ad : inout std_logic_vector(31 downto 0); -- signal c_be_n : out std_logic_vector(3 downto 0); -- signal irdy_n : out std_logic; -- signal par : inout std_logic; -- signal perr_n : out std_logic; -- signal sv_read_data : out std_logic_vector(31 downto 0) -- for test );
設定項目 | 設定内容 |
---|---|
set_address |
std_logic_vector(31 downto 0) リード対象のアドレスを指定。 |
set_ad_perr |
std_logic アドレスに対するパリティエラーを設定。 パリティ線 PAR を 正常パリティ(OK)にするかエラーパリティ(NG)にするかを選択する。 0:OK、 1:NG |
set_be_n |
std_logic_vector(3 downto 0) リードデータに対する C/BE[3:0]# 信号のバイトイネーブル信号 be_n の値を設定。 |
その他の信号 |
clk 以下の信号は本procedure と外部信号を接続する為のもの。 ユーザの編集禁止。 なお、sv_read_data はリードしたデータを判り易く値として波形表示する為のものである。 |
type SET_DATA is record WR_DATA : std_logic_vector(31 downto 0); BEn : std_logic_vector(3 downto 0); PERR : std_logic; -- 1: ng_parity, 0: ok_parity LAST : std_logic; -- 1: last data, 0: non-last data end record; type SET_DATA_ARRAY is array (0 to (MAX_DATA-1) ) of SET_DATA; procedure pci_memory_burst_write ( set_address : in std_logic_vector(31 downto 0); -- set_ad_perr : in std_logic; -- 1: ng_parity, 0: ok_parity set_data_array : in SET_DATA_ARRAY; ---- signal clk : in std_logic; -- signal trdy_n : in std_logic; -- signal devsel_n : in std_logic; -- signal frame_n : out std_logic; -- signal ad : inout std_logic_vector(31 downto 0); -- signal c_be_n : out std_logic_vector(3 downto 0); -- signal irdy_n : out std_logic; -- signal par : inout std_logic -- );
設定項目 | 設定内容 | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
set_address |
std_logic_vector(31 downto 0) ライト対象の先頭アドレスを指定。 |
||||||||||
set_ad_perr |
std_logic アドレスに対するパリティエラーを設定。 パリティ線 PAR を 正常パリティ(OK)にするかエラーパリティ(NG)にするかを選択する。 0:OK、 1:NG |
||||||||||
set_wr_data |
std_logic_vector(31 downto 0) ライトするデータを設定。 |
||||||||||
set_data_array |
ライトデータ数分のデータレコードの配列 pci_memory_burst_write を発行する直前に予め準備して置く。 これはVHDLが、データレコードの内容を pci_memory_burst_write 内に直接記述できない仕様になっているので、別途用意するものとした為である。 本サブプログラムでは最大バーストデータ数(MAX_DATA)を4にしているので、4個のレコードの配列とする。 具体的な使用例は後出のテストベンチの例参照。 下表に1レコードの内容を示す。
| ||||||||||
その他の信号 |
clk 以下の信号は本procedure と外部信号を接続する為のもの。 ユーザの編集禁止。 |
subtype BEn is std_logic_vector(3 downto 0); type BEn_ARRAY is array (0 to (MAX_DATA-1) ) of BEn; procedure pci_memory_burst_read ( set_address : in std_logic_vector(31 downto 0); -- set_ad_perr : in std_logic; -- 1: ng_parity, 0: ok_parity set_data_no : integer range 1 to MAX_DATA; -- set_be_n_array : in BEn_ARRAY; -- ---- signal clk : in std_logic; -- signal trdy_n : in std_logic; -- signal devsel_n : in std_logic; -- signal frame_n : out std_logic; -- signal ad : inout std_logic_vector(31 downto 0); -- signal c_be_n : out std_logic_vector(3 downto 0); -- signal irdy_n : out std_logic; -- signal par : inout std_logic; -- signal perr_n : out std_logic; -- signal sva_read_data : out DATA_ARRAY -- for test );
設定項目 | 設定内容 |
---|---|
set_address |
std_logic_vector(31 downto 0) リード対象の先頭アドレスを指定。 |
set_ad_perr |
std_logic アドレスに対するパリティエラーを設定。 パリティ線 PAR を 正常パリティ(OK)にするかエラーパリティ(NG)にするかを選択する。 0:OK、 1:NG |
set_data_no |
integer range 1 to MAX_DATA バーストリードするデータ数を指定。 本サブプログラムでは最大バーストデータ数(MAX_DATA)を4にしているので、データ数は1〜4個で設定する。 |
set_be_n_array |
BEn_ARRAY リードデータに対する C/BE[3:0]# 信号のバイトイネーブル信号 be_n の値を BEn(std_logic_vector(3 downto 0)) の配列で設定。 本サブプログラムでは最大バーストデータ数(MAX_DATA)を4にしているので、配列の要素数は1〜4個。 |
その他の信号 |
clk 以下の信号は本procedure と外部信号を接続する為のもの。 ユーザの編集禁止。 なお、sva_read_data はリードしたデータを判り易く値として波形表示する為のものである。 |
procedure pci_init ( signal v_idsel : out std_logic_vector(31 downto 0); -- signal frame_n : out std_logic; -- signal ad : inout std_logic_vector(31 downto 0); -- signal c_be_n : out std_logic_vector(3 downto 0); -- signal irdy_n : out std_logic; -- signal par : inout std_logic; -- signal lock_n : out std_logic; -- signal req_n : out std_logic; -- signal perr_n : inout std_logic; -- signal serr_n : out std_logic; -- signal inta_n : out std_logic; -- signal intb_n : out std_logic; -- signal intc_n : out std_logic; -- signal intd_n : out std_logic -- );
設定項目 | 設定内容 |
---|---|
無し |
PCIバス信号の signal定義部分で各信号の値を初期化する代わりに、本サブプログラムで'Z'や'1'にイニシャライズするもので、使用は必須ではない。 シミュレーション波形の信号レベル不定部分(赤色)を無くし、見栄えを良くする為に用意した。 全信号が本procedure と外部信号を接続する為のものであり、ユーザの編集禁止。 |