PCIバステストベンチ用ターゲットIP

TGT8_plus.VHD


リンク元 PCIバス向けテストベンチ用サブプログラム

●PCIバステストベンチ用ターゲットIP TGT8_plus.VHD
-------------------------------------------------------------------------------------
-- File Name    : TGT8_plus.VHD
-- Function     : pci_master_model for simulation
-- Editor       : F.O. (ProXi)
-- Date         : 2018/11/15
-- 【備考】     : 詳細は  https://www.proxi.co.jp/technolo/pci_bus_test_bench.htm 参照
--              : 本ソースは ASIAN記法 (Attributed SIgnAl Naming)  で記述している。
--              :   詳細は https://www.proxi.co.jp/technolo/asian.htm 参照
-------------------------------------------------------------------------------------
-- 【注記】本ファイルは以下のソースファイルを一部編集したものである。
--  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 は受信動作が終了したら自動クリアされる。
--
-------------------------------------------------------------------------------------
-- library for TGT8.vhd                                                                             --px0
-------------------------------------------------------------------------------------
-- package を追加するが、煩雑化防止の為別ファイルにせず、TGT8_plus.VHD に含める
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
USE ieee.numeric_std.ALL;

package pci_pac is
    -- parity generator
    function even_parity_calculator (
        ad          : std_logic_vector;
        c_be_n      : std_logic_vector
    ) return std_logic;

end pci_pac;

package body pci_pac is
    function even_parity_calculator (
        ad          : std_logic_vector;
        c_be_n      : std_logic_vector
    ) return std_logic is

        variable xc_par : std_logic;

    begin
        xc_par := '0';
        for i in ad'range loop
            xc_par := xc_par xor ad(i);
        end loop;

        for i in c_be_n'range loop
            xc_par := xc_par xor c_be_n(i);
        end loop;
        
        return (xc_par);

    end even_parity_calculator;

end pci_pac;

-------------------------------------------------------------------------------------
-- 以下がオリジナルの TGT8_plus.VHD 本体部分                                                        --px0
-------------------------------------------------------------------------------------
-- TGT8
-------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

use work.pci_pac.all;                                                                               --px0

entity TGT8 is
    port(
        -- PCIバス信号ピン(ターゲット8で使用する信号)           --
        PCICLK      : in    std_logic;                      -- PCIバスクロック
        RST_n       : in    std_logic;                      -- 非同期リセット
        PCIAD       : inout std_logic_vector(31 downto 0);  -- アドレス/データバス
        C_BE_n      : in    std_logic_vector(3 downto 0);   -- PCIバスコマンド/バイトイネーブル
        FRAME_n     : in    std_logic;                      -- フレーム
        IRDY_n      : in    std_logic;                      -- イニシエータレディ
        DEVSEL_n    : out   std_logic;                      -- デバイスセレクション
        TRDY_n      : out   std_logic;                      -- ターゲットレディ
        IDSEL       : in    std_logic;                      -- コンフィグレーションデバイスセレクト
        INTA_n      : out   std_logic;                      -- 割り込み出力 INTA#
        STOP_n      : out   std_logic;                      -- 転送ストップ要求
        PAR         : inout std_logic;                      -- パリティビット
        PERR_n      : out    std_logic;                     -- パリティエラー                       --px0

        -- PCIバス信号ピン(ターゲット8で未使用な信号)           --
        --PERR_n    : out   std_logic;                      -- パリティエラー                       --px0
        SERR_n      : out   std_logic;                      -- システムエラー
        REQ_n       : out   std_logic;                      -- バス使用要求信号
        GNT_n       : in    std_logic;                      -- バス使用許諾信号
        INTB_n      : out   std_logic;                      -- 割り込み出力 INTB#
        INTC_n      : out   std_logic;                      -- 割り込み出力 INTC#
        INTD_n      : out   std_logic;                      -- 割り込み出力 INTD#
        LOCK_n      : in    std_logic;                      -- 排他アクセス制御
        SBO_n       : inout std_logic;                      -- スヌープバックオフ
        SDONE_n     : inout std_logic;                      -- スヌープ完了

        -- ローカルバス信号ピン
        MEM_ADRS    : out   std_logic_vector(23 downto 2);  -- メモリアドレスバス(16Mバイト)
        MEM_DATA    : inout std_logic_vector(31 downto 0);  -- メモリデータバス
        MEM_CEn     : out   std_logic;                      -- SRAM0〜3 /CE
        MEM_OEn     : out   std_logic;                      -- SRAM0〜3 /OE
        MEM_WE0n    : out   std_logic;                      -- SRAM0 /WE
        MEM_WE1n    : out   std_logic;                      -- SRAM1 /WE
        MEM_WE2n    : out   std_logic;                      -- SRAM2 /WE
        MEM_WE3n    : out   std_logic;                      -- SRAM3 /WE

        -- 外部割り込み入力ピン
        INT_IN3     : in    std_logic;                      -- 割り込み入力3
        INT_IN2     : in    std_logic;                      -- 割り込み入力2
        INT_IN1     : in    std_logic;                      -- 割り込み入力1
        INT_IN0     : in    std_logic;                      -- 割り込み入力0
                                                            
        -- I/O ポート  di0..7, do0..7                                                               --px0
        sv_do       : out std_logic_vector(7 downto 0);     -- base +4 rd/wr
        av_di       : in  std_logic_vector(7 downto 0);     -- base +6 rd only

        -- for test                                                                                 --px0
        tp0         : out   std_logic;
        tp1         : out   std_logic;
        tp2         : out   std_logic;
        tp3         : out   std_logic;
        tp4         : out   std_logic;
        tp5         : out   std_logic;
        tp6         : out   std_logic;
        tp7         : out   std_logic;
        tp_v0       : out   std_logic_vector(31 downto 0);
        tp_v1       : out   std_logic_vector(3 downto 0); 
        tp_v2       : out   std_logic_vector(31 downto 0);
        tp_v3       : out   std_logic_vector(3 downto 0); 
        cv_cur_state : out  std_logic_vector(2 downto 0)  

    );
end entity TGT8;

architecture RTL of TGT8 is


-- ************************************************************************* --
-- **********    レジスタ/定数 定義部分
-- ************************************************************************* --

    -- PCIバスコマンド/アドレス/IDSELホールドレジスタ --
    signal PCI_BusCommand           : std_logic_vector(3 downto 0);     -- PCIバスコマンドレジスタ
    signal PCI_Address              : std_logic_vector(31 downto 0);    -- PCIアドレスレジスタ
    signal PCI_IDSEL                : std_logic;                        -- IDSELレジスタ

    -- ローカルバスシーケンサ スタートフラグ
    signal LOCAL_Bus_Start  : std_logic;
    -- ローカルバスシーケンサ データ転送完了フラグ
    signal LOCAL_DTACK              : std_logic;

    -- トライステートバッファ制御用のフリップフロップ定義 --
    -- PCIバス信号線
    signal PCIAD_HiZ                : std_logic;                        -- ADポート出力ドライブ制御
    signal PCIAD_Port               : std_logic_vector(31 downto 0);    -- ADポート出力レジスタ
    signal DEVSEL_HiZ, DEVSEL_Port  : std_logic;                        -- DEVSEL#出力ドライブ制御/出力レジスタ
    signal TRDY_HiZ, TRDY_Port      : std_logic;                        -- TRDY#出力ドライブ制御/出力レジスタ
    signal INTA_HiZ, INTA_Port      : std_logic;                        -- INTA#出力ドライブ制御/出力レジスタ
    signal PAR_HiZ,  PAR_Port       : std_logic;                        -- PAR出力ドライブ制御/出力レジスタ
    signal STOP_HiZ, STOP_Port      : std_logic;                        -- STOP出力ドライブ制御/出力レジスタ

    signal PERR_HiZ, PERR_Port      : std_logic;                        -- ダミーノード(ターゲット8未使用)
    signal SERR_HiZ, SERR_Port      : std_logic;
    signal REQ_HiZ,  REQ_Port       : std_logic;
    signal INTB_HiZ, INTB_Port      : std_logic;
    signal INTC_HiZ, INTC_Port      : std_logic;
    signal INTD_HiZ, INTD_Port      : std_logic;
    signal SBO_HiZ,  SBO_Port       : std_logic;
    signal SDONE_HiZ,SDONE_Port     : std_logic;

    --  PCIバスコマンド(ビットパターン定義) --
    -- コンフィギュレーションサイクル
    constant PCI_CfgCycle           : std_logic_vector(3 downto 1)  := ("101");
    constant PCI_CfgReadCycle       : std_logic_vector(3 downto 0)  := ("1010");
    constant PCI_CfgWriteCycle      : std_logic_vector(3 downto 0)  := ("1011");
    -- メモリサイクル
    constant PCI_MemCycle           : std_logic_vector(3 downto 1)  := ("011");
    constant PCI_MemReadCycle       : std_logic_vector(3 downto 0)  := ("0110");
    constant PCI_MemWriteCycle      : std_logic_vector(3 downto 0)  := ("0111");
    -- I/Oサイクル
    constant PCI_IoCycle            : std_logic_vector(3 downto 1)  := ("001");
    constant PCI_IoReadCycle        : std_logic_vector(3 downto 0)  := ("0010");
    constant PCI_IoWriteCycle       : std_logic_vector(3 downto 0)  := ("0011");

    -- コンフィギュレーションレジスタ群(読み出し専用レジスタ) --
    constant CFG_VendorID           : std_logic_vector(15 downto 0) := (X"4949");   -- ベンダID 4949h
    constant CFG_DeviceID           : std_logic_vector(15 downto 0) := (X"7777");   -- デバイスID 7777h
    constant CFG_Command            : std_logic_vector(15 downto 0) := (X"0000");
    constant CFG_Status             : std_logic_vector(15 downto 0) := (X"0200");   -- DEVSEL# 中速応答
    constant CFG_BaseClass          : std_logic_vector(7  downto 0) := (X"05");     -- 05h RAM
    constant CFG_SubClass           : std_logic_vector(7  downto 0) := (X"00");
    constant CFG_ProgramIF          : std_logic_vector(7  downto 0) := (X"00");
    constant CFG_RevisionID         : std_logic_vector(7  downto 0) := (X"01");     -- レビジョン 1
    constant CFG_HeaderType         : std_logic_vector(7  downto 0) := (X"00");     -- ヘッダタイプ0
    constant CFG_Int_Pin            : std_logic_vector(7  downto 0) := (X"01");     -- INTA#のみ使用

    -- コンフィギュレーションレジスタ群(読み書きレジスタ) --
    -- コマンドレジスタ メモリイネーブルビット
    signal CFG_Cmd_Mem              : std_logic;
    -- コマンドレジスタ I/Oイネーブルビット
    signal CFG_Cmd_Io               : std_logic;
    -- ベースアドレスレジスタ(メモリ空間)
    signal CFG_Base_Addr0           : std_logic_vector(31 downto 24);

    -- ベースアドレスレジスタ(I/O空間)
    --signal CFG_Base_Addr1         : std_logic_vector(15 downto 2);                                --px0
    signal CFG_Base_Addr1           : std_logic_vector(15 downto 3);                                --px0

    -- インタラプトラインレジスタ
    signal CFG_Int_Line : std_logic_vector(7 downto 0);

    -- アドレスデコードフラグ
    signal Hit_Device               : std_logic;                        -- デバイスヒット
    signal Hit_Memory               : std_logic;                        -- メモリサイクルヒット
    signal Hit_Io                   : std_logic;                        -- I/Oサイクルヒット
    signal Hit_Config               : std_logic;                        -- コンフィグレーションサイクルヒット

    -- ローカルバス トライステート制御
    signal MEM_DATA_HiZ             : std_logic;                        -- メモリデータバストライステート制御
    signal MEM_DATA_Port            : std_logic_vector(31 downto 0);    -- メモリデータバス

    --  割り込み制御レジスタ群
    -- インタラプトステータス/フラグレジスタ
    signal INT_STAT3                : std_logic;
    signal INT_STAT2                : std_logic;
    signal INT_STAT1                : std_logic;
    signal INT_STAT0                : std_logic;
    -- インタラプトマスク(許可)レジスタ
    signal INT_MSK3                 : std_logic;
    signal INT_MSK2                 : std_logic;
    signal INT_MSK1                 : std_logic;
    signal INT_MSK0                 : std_logic;

    -- 改訂の為の追加信号分                                                                         --px0
    signal xmv_di_q                 : std_logic_vector(7 downto 0);
    signal xsv_di_q0                : std_logic_vector(7 downto 0);
    signal xsv_do                   : std_logic_vector(7 downto 0);

    signal xs_PAR_Port_q            : std_logic;
    signal xc_adr_par               : std_logic;
    signal xc_data_par              : std_logic;

    signal xsv_adr                  : std_logic_vector(31 downto 0);
    signal xsv_data                 : std_logic_vector(31 downto 0);
    signal xsv_command              : std_logic_vector(3 downto 0);
    signal xsv_be_n                 : std_logic_vector(3 downto 0);

    signal xs_frame                 : std_logic;
    signal xs_frame_q               : std_logic;
    signal xsp_frame_on             : std_logic;
    signal xsp_frame_on_q           : std_logic;
    signal xs_trdy                  : std_logic;
    signal xs_trdy_q                : std_logic;

begin


-- ************************************************************************* --
-- **********    同時処理文
-- ************************************************************************* --
    -- トライステートバッファ動作
    MEM_DATA    <= (others => 'Z') when MEM_DATA_HiZ = '1' else MEM_DATA_Port;
    PCIAD       <= (others => 'Z') when PCIAD_HiZ = '1'    else PCIAD_Port;
    DEVSEL_n    <= 'Z'    when DEVSEL_HiZ = '1' else DEVSEL_Port;
    TRDY_n      <= 'Z'    when TRDY_HiZ = '1'   else TRDY_Port;
    INTA_n      <= 'Z'    when INTA_HiZ = '1'   else INTA_Port;
    ---PAR      <= 'Z'    when PAR_HiZ = '1'    else PAR_Port;                                      --px0
    PAR         <= 'Z'    when PAR_HiZ = '1'    else xs_PAR_Port_q;                                 --px0
    STOP_n      <= 'Z'    when STOP_HiZ = '1'   else STOP_Port;

    PERR_n      <= 'Z'    when PERR_HiZ = '1'   else PERR_Port;                                     --px0

    -- 未使用ピンの状態設定(ハイインピーダンス状態に固定)
    SERR_n      <= 'Z'    when SERR_HiZ = '1'   else    SERR_Port;  SERR_HiZ    <= '1'; SERR_Port   <= '0';
    REQ_n       <= 'Z'    when REQ_HiZ = '1'    else    REQ_Port;   REQ_HiZ     <= '1'; REQ_Port    <= '0';
    INTB_n      <= 'Z'    when INTB_HiZ = '1'   else    INTB_Port;  INTB_HiZ    <= '1'; INTB_Port   <= '0';
    INTC_n      <= 'Z'    when INTC_HiZ = '1'   else    INTC_Port;  INTC_HiZ    <= '1'; INTC_Port   <= '0';
    INTD_n      <= 'Z'    when INTD_HiZ = '1'   else    INTD_Port;  INTD_HiZ    <= '1'; INTD_Port   <= '0';
    SBO_n       <= 'Z'    when SBO_HiZ = '1'    else    SBO_Port;   SBO_HiZ     <= '1'; SBO_Port    <= '0';
    SDONE_n     <= 'Z'    when SDONE_HiZ = '1'  else    SDONE_Port; SDONE_HiZ   <= '1'; SDONE_Port  <= '0';


    ----------------------------------------------
    -- DO                                                                                           --px0
    sv_do <= xsv_do;

    -- DI synchronizer                                                                              --px0
    process (RST_n, PCICLK) begin
        if (RST_n = '0') then
            xmv_di_q    <= (others => '0');
            xsv_di_q0   <= (others => '0');
        elsif (PCICLK'event and PCICLK = '1') then
            xmv_di_q    <= av_di;
            xsv_di_q0   <= xmv_di_q;
        end if;
    end process;

    -- for test                                                                                     --px0
    tp0     <= Hit_Config;
    tp1     <= Hit_Io;
    tp2     <= xc_adr_par;
    tp3     <= xc_data_par;
    tp4     <= PAR_HiZ;
    tp5     <= PAR_Port;
    tp6     <= xs_PAR_Port_q;
    tp7     <= 'Z';
    tp_v0   <= xsv_adr;
    tp_v1   <= xsv_command;
    tp_v2   <= xsv_data;
    tp_v3   <= xsv_be_n;


    ----------------------------------------------
    -- address, data latch                                                                          --px0
    ----------------------------------------------
    xs_frame        <= not FRAME_n;
    xsp_frame_on    <= xs_frame and (not xs_frame_q);
    xs_trdy         <= not TRDY_Port;

    adr_data_latch : process( PCICLK, RST_n ) begin
        if ( RST_n = '0' ) then    
            xs_frame_q      <= '0';
            xsp_frame_on_q  <= '0';
            xs_trdy_q       <= '0';
            xsv_adr         <= (others => '0');
            xsv_command     <= (others => '0');
            xsv_data        <= (others => '0');
            xsv_be_n        <= (others => '0');

        elsif (PCICLK'event and PCICLK = '1') then
            xs_frame_q      <= xs_frame;
            xsp_frame_on_q  <= xsp_frame_on;
            xs_trdy_q       <= xs_trdy;

            if (xsp_frame_on = '1') then
                xsv_adr     <= PCIAD;
                xsv_command <= C_BE_n;
            end if;

            if (xs_trdy = '1') then
                xsv_data    <= PCIAD;
                xsv_be_n    <= C_BE_n;
            end if;
        end if;
    end process;

    xc_adr_par <= even_parity_calculator (xsv_adr, xsv_command);
    xc_data_par <= even_parity_calculator (xsv_data, xsv_be_n);


    ----------------------------------------------
    -- parity checker                                                                               --px0
    ----------------------------------------------
    parity_checker0 : process( PCICLK, RST_n ) begin
        if (RST_n = '0') then    
            PERR_Port   <= '1';
            PERR_HiZ    <= '1';

        elsif (PCICLK'event and PCICLK = '1') then
            if (xsp_frame_on_q = '1') then
                if (xc_adr_par /= PAR) then
                    PERR_Port   <= '0';
                    PERR_HiZ    <= '0';
                else
                    PERR_Port   <= '1';
                    PERR_HiZ    <= '1';
                end if;
            end if;

            if (xs_trdy_q = '1') then
                if (xc_data_par /= PAR) then
                    PERR_Port   <= '0';
                    PERR_HiZ    <= '0';
                else
                    PERR_Port   <= '1';
                    PERR_HiZ    <= '1';
                end if;
            end if;
        end if;
    end process;

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


-- ************************************************************************* --
-- **********    PCIターゲットシーケンサ
-- ************************************************************************* --

PCI_TGT_Seq : process( PCICLK, RST_n )

    -- PCIターゲットシーケンサ ステートバリューレジスタ --
    variable PCI_CURRENT_STATE  : std_logic_vector (2 downto 0);    -- 現在のステート
    variable PCI_NEXT_STATE     : std_logic_vector (2 downto 0);    -- 次のステート

    -- PCIターゲットシーケンサ ステートマシン定義
    constant BUS_IDLE           : std_logic_vector (2 downto 0) :="000";
    constant ADRS_COMPARE       : std_logic_vector (2 downto 0) :="001";
    constant BUS_BUSY           : std_logic_vector (2 downto 0) :="010";
    constant WAIT_IRDY          : std_logic_vector (2 downto 0) :="011";
    constant WAIT_LOCAL_ACK     : std_logic_vector (2 downto 0) :="100";
    constant ACC_COMPLETE       : std_logic_vector (2 downto 0) :="101";
    constant DIS_CONNECT        : std_logic_vector (2 downto 0) :="110";
    constant TURN_AROUND        : std_logic_vector (2 downto 0) :="111";

    -- バースト転送アドレスカウンタ
    variable Adrs_Pointer       : unsigned(23 downto 2);
    -- バースト転送アドレス上限フラグ
    variable Point_LAST_ADRS    : boolean;

begin
    -- ********** バースト転送上限アドレス判定 ********** --
    if (RST_n = '0') then    -- PCIバスリセット時(非同期リセット)
        Point_LAST_ADRS     := FALSE;
    else
        -- バースト転送アドレスが最上位を示していたら
        if (Adrs_Pointer = "1111111111111111111111") then
            Point_LAST_ADRS := TRUE;
        else
            Point_LAST_ADRS := FALSE;
        end if;
    end if;


    -- ********** リセット時動作 ********** --
    if (RST_n = '0') then                               -- PCIバスリセット時(非同期リセット)
        PCI_CURRENT_STATE   := BUS_IDLE;                -- ステートマシン IDLE状態 リセット
        PCI_NEXT_STATE      := BUS_IDLE;                -- ステートマシン IDLE状態 リセット

        LOCAL_Bus_Start     <= '0';                     -- ローカルバスシーケンサ スタートフラグ クリア

        PCI_BusCommand <= (others => '0');              -- PCIバスコマンドレジスタ クリア
        PCI_Address         <= (others => '0');         -- PCIバスアドレスレジスタ クリア
        PCI_IDSEL           <= '0';                     -- IDSELレジスタ クリア
        Adrs_Pointer        := ( others => '0' );       -- バースト転送時アドレスカウンタ クリア

        -- 制御出力端子をハイインピーダンス
        PCIAD_HiZ           <= '1';
        DEVSEL_HiZ          <= '1'; DEVSEL_Port <= '1'; -- DEVSEL#="H"
        TRDY_HiZ            <= '1'; TRDY_Port   <= '1'; -- TRDY#="H"
        STOP_HiZ            <= '1'; STOP_Port   <= '1'; -- STOP#="H"
        PAR_HiZ             <= '1';                     -- PAR_Portはパリティジェネレータで生成

        xs_PAR_Port_q       <= '0';                                                                 --px0

    -- ********** PCIターゲットシーケンサ ステートマシン ********** --
    elsif (PCICLK'event and PCICLK = '1') then
        PCI_CURRENT_STATE   := PCI_NEXT_STATE;          -- ステートマシン制御

        xs_PAR_Port_q       <= PAR_Port;                                                            --px0

        case PCI_CURRENT_STATE is
            -- ********** BUS_IDLE時の動作 ********** --
            when BUS_IDLE =>        -- トランザクションの開始待ち
                if (FRAME_n = '0' and IRDY_n = '1') then    -- トランザクション開始
                    PCI_BusCommand  <= C_BE_n;              -- PCIバスコマンド取得
                    PCI_Address     <= PCIAD;               -- アドレス取得
                    PCI_IDSEL       <= IDSEL;               -- IDSEL取得
                    Adrs_Pointer    := unsigned(PCIAD(23 downto 2));
                    PCI_NEXT_STATE  := ADRS_COMPARE;

                else                                        -- バスアイドル時このステートにとどまる
                    PCI_NEXT_STATE  := BUS_IDLE;
                end if;

            -- ********** ADRS_COMPARE時の動作 ********** --
            when ADRS_COMPARE =>    -- アドレスデコード結果を調べる
                if (Hit_Device = '1') then                      -- 自分が選択された
                    DEVSEL_Port     <= '0'; DEVSEL_HiZ <= '0';  -- DEVLSEL#アサート
                    TRDY_HiZ        <= '0';                     -- TRDY# を "H"にドライブ
                    STOP_HiZ        <= '0';                     -- STOP# を "H"にドライブ
                    PCI_NEXT_STATE  := WAIT_IRDY;               -- イニシエータレディを待つステートへ
                    
                else    -- 自分が選択されていない
                    PCI_NEXT_STATE := BUS_BUSY;    -- トランザクションの終了を待つステートへ
                end if;

            -- ********** BUS_BUSY時の動作 ********** --
            when BUS_BUSY =>        -- トランザクション終了待ち
                if (FRAME_n = '1' and IRDY_n = '1') then    -- トランザクション終了(アイドル)
                    PCI_NEXT_STATE := BUS_IDLE;             -- トランザクション開始待ちステートへ

                else    -- トランザクション中ならこのステートにとどまる
                    PCI_NEXT_STATE := BUS_BUSY;
                end if;

            -- ********** WAIT_IRDY時の動作 ********** --
            when WAIT_IRDY =>       -- イニシエータレディ待ち
                if (IRDY_n = '0') then                      -- イニシエータの準備完了
                    if (PCI_BusCommand(0) = '0') then       -- リードサイクルのとき
                        PCIAD_HiZ   <= '0';                 -- PCIAD[31:0]バスドライブ
                    end if;
                    LOCAL_Bus_Start <= '1';                 -- ローカルバスシーケンサ スタート!
                    PCI_NEXT_STATE := WAIT_LOCAL_ACK;       -- ローカルバスシーケンサ終了待ちステートへ

                else                -- イニシエータの準備がまだならこのステートにとどまる
                    PCI_NEXT_STATE := WAIT_IRDY;
                end if;

            -- ********** WAIT_LOCAL_ACK時の動作 ********** --
            when WAIT_LOCAL_ACK =>  -- ローカルバスシーケンサ終了待ち
                LOCAL_Bus_Start     <= '0';                 -- ローカルバスシーケンサ スタートフラグ クリア

                if (LOCAL_DTACK = '1') then                 -- ローカルバスシーケンサ データ転送完了
                    TRDY_Port       <= '0';                 -- TRDY# アサート
                    PCI_NEXT_STATE  := ACC_COMPLETE;        -- アクセス完了ステートへ

                else                                        -- ローカルバスシーケンサの準備がまだならこのステートにとどまる
                    PCI_NEXT_STATE  := WAIT_LOCAL_ACK;
                end if;

            -- ********** ACC_COMPLETE時の動作 ********** --
            when ACC_COMPLETE =>    -- アクセス完了ステート
                TRDY_Port           <= '1';                 -- TRDY# ディアサート
                PCIAD_HiZ           <= '1';                 -- PCIAD[31:0]バスドライブ解放
                if (PCI_BusCommand(0) = '0') then           -- リードサイクルであれば
                    PAR_HiZ         <= '0' ;                -- PAR ドライブ開始
                end if;

                if (FRAME_n = '0') then                     -- FRAME# = 'L'ならバースト転送要求
                    if ( Hit_Memory = '1' and PCI_Address(1 downto 0) = "00"
                        and Point_LAST_ADRS = FALSE) then
                                                            -- メモリ空間&アドレスインクリメントモード=リニアバースト
                                                            -- アドレスが最終アドレスではない
                        Adrs_Pointer                := Adrs_Pointer + 1 ;       -- アドレスをインクリメント
                        PCI_Address(23 downto 2)    <= std_logic_vector(Adrs_Pointer);
                        PCI_NEXT_STATE              := WAIT_IRDY;               -- イニシエータレディを待つステートへ

                    else
                        STOP_Port                   <= '0';                     -- STOP# アサート
                        PCI_NEXT_STATE              := DIS_CONNECT;             -- ディスコネクトステートへ
                    end if;

                else                                            -- 単一データフェーズのトランザクションの時
                    DEVSEL_Port         <= '1';                 -- DEVSEL#ディアサート
                    PCI_NEXT_STATE      := TURN_AROUND;         --  ターンアラウンドステートへ
                end if;

            -- ********** DIS_CONNECT時の動作 ********** --
            when DIS_CONNECT =>        -- ディスコネクト処理
                if (FRAME_n = '1') then                         -- イニシエータがSTOP#を認識
                    DEVSEL_Port         <= '1';                 -- DEVSEL# ディアサート
                    STOP_Port           <= '1';                 -- STOP# ディアサート
                    PCI_NEXT_STATE      := TURN_AROUND;         -- 次はTURN_AROUNDステートへ

                else                                            -- イニシエータがSTOP#を認識していなければこのステートにとどまる
                    PCI_NEXT_STATE      := DIS_CONNECT;
                end if;

            -- ********** TURN_AROUND時の動作 ********** --
            when TURN_AROUND =>        -- ターンアラウンドステート

                DEVSEL_HiZ          <= '1';                 -- DEVSEL#ドライブ解放
                TRDY_HiZ            <= '1';                 -- TRDY#ドライブ解放
                STOP_HiZ            <= '1';                 -- STOP#ドライブ解放
                PAR_HiZ             <= '1';                 -- PARドライブ解放
                PCI_NEXT_STATE      := BUS_IDLE;            -- トランザクション開始待ちステートへ

            -- ****************************************** --
            when others => null;    -- これ以外の値では何もしない場合でも必ず入れる

        end case;

        cv_cur_state    <= PCI_CURRENT_STATE;               -- for test                             --px0

    end if;

end process PCI_TGT_Seq;


-- ************************************************************************* --
-- **********    ローカルバスシーケンサ
-- ************************************************************************* --

-- ローカルアドレスバスへメモリアドレスを出力
MEM_ADRS(23 downto 2) <= PCI_Address(23 downto 2);


LOCAL_BUS_Seq : process( PCICLK, RST_n )
    -- ローカルバスシーケンサ ステートバリューレジスタ --
    variable LOCAL_CURRENT_STATE    : std_logic_vector (2 downto 0);    -- 現在のステート
    variable LOCAL_NEXT_STATE       : std_logic_vector (2 downto 0);    -- 次のステート

    -- ローカルバスシーケンサ ステートマシン定義
    constant LOCAL_IDLE             : std_logic_vector(2 downto 0) := "000";
    constant LOCAL_MEM_ACCESS       : std_logic_vector(2 downto 0) := "001";
    constant LOCAL_IO_ACCESS        : std_logic_vector(2 downto 0) := "010";
    constant LOCAL_CFG_ACCESS       : std_logic_vector(2 downto 0) := "011";
    constant LOCAL_STATE_COMP       : std_logic_vector(2 downto 0) := "100";

    -- メモリアクセス ウェイトカウンタ
    variable WAIT_Count             : unsigned(3 downto 0);

    -- 割り込み入力状態保存フラグ
    variable INT_IN3_flg            : std_logic;
    variable INT_IN2_flg            : std_logic;
    variable INT_IN1_flg            : std_logic;
    variable INT_IN0_flg            : std_logic;

begin
    -- ********** リセット時動作 ********** --
    if ( RST_n = '0' ) then    -- PCIバスリセットがアサートされたとき
        -- ステートバリューレジスタクリア
        LOCAL_CURRENT_STATE := (others => '0');    -- ローカルバスシーケンサ リセット
        LOCAL_NEXT_STATE    := (others => '0');    -- ローカルバスシーケンサ リセット

        -- コンフィグレーションレジスタ リード/ライトレジスタ インタラプトライン クリア
        CFG_Cmd_Mem         <= '0';
        CFG_Cmd_Io          <= '0';
        CFG_Base_Addr0      <= (others => '0');
        CFG_Base_Addr1      <= (others => '0');
        CFG_Int_Line        <= (others => '0');

        -- ローカルバス制御線ディセーブル
        MEM_CEn             <= '1';                 -- SRAM0〜3 /CE
        MEM_OEn             <= '1';                 -- SRAM0〜3 /OE
        MEM_WE0n            <= '1';                 -- SRAM0 /WE
        MEM_WE1n            <= '1';                 -- SRAM1 /WE
        MEM_WE2n            <= '1';                 -- SRAM2 /WE
        MEM_WE3n            <= '1';                 -- SRAM3 /WE
        ----MEM_DATA_HiZ    <= '0';                 -- データバス出力方向                           --px0
        MEM_DATA_HiZ        <= '1';                 -- ローカルデータバス入力方向                   --px0

        PCIAD_Port          <= (others => '0');     -- AD出力レジスタ クリア
        MEM_DATA_Port       <= (others => '0');     -- MEM_DATA出力レジスタ クリア

        -- メモリアクセス ウェイトカウンタ クリア
        WAIT_Count          := (others => '0');

        -- ローカルバスシーケンサ データ転送完了フラグ クリア
        LOCAL_DTACK         <= '0';

        -- 割り込み制御レジスタ --
        INT_MSK3            <= '0';                 -- 割り込みマスクレジスタ クリア
        INT_MSK2            <= '0';
        INT_MSK1            <= '0';
        INT_MSK0            <= '0';
        INT_STAT3           <= '0';                 -- 割り込み要求レジスタ クリア
        INT_STAT2           <= '0';
        INT_STAT1           <= '0';
        INT_STAT0           <= '0';
        INT_IN3_flg         := '0';                 -- 割り込み入力フラグ クリア
        INT_IN2_flg         := '0';
        INT_IN1_flg         := '0';
        INT_IN0_flg         := '0';
        INTA_HiZ            <='1';                  -- INTA# ハイインピーダンス
        INTA_Port           <= '0';

        xsv_do <= (others => '0');                                                                  --px0

    elsif (PCICLK'event and PCICLK = '1') then
        -- **********    割り込みコントローラ     ********** --
        if (INT_IN3 = '0' and INT_IN3_flg = '1') then   -- 外部割り込み入力3 "L"
            INT_STAT3   <= '1';                         -- 割り込みステータスレジスタ3
        end if;
        if (INT_IN2 = '0' and INT_IN2_flg = '1') then   -- 外部割り込み入力2 "L"
            INT_STAT2   <= '1';                         -- 割り込みステータスレジスタ2
        end if;

        if (INT_IN1 = '0' and INT_IN1_flg = '1') then   -- 外部割り込み入力1 "L"
            INT_STAT1   <= '1';                         -- 割り込みステータスレジスタ1
        end if;
        if (INT_IN0 = '0' and INT_IN0_flg = '1') then   -- 外部割り込み入力0 "L"
            INT_STAT0   <= '1';                         -- 割り込みステータスレジスタ0
        end if;

        if (
            (INT_STAT3 = '1' and INT_MSK3 = '1')        -- チャネル3割り込み発生&割り込み可
            or
            (INT_STAT2 = '1' and INT_MSK2 = '1')        -- チャネル2割り込み発生&割り込み可
            or
            (INT_STAT1 = '1' and INT_MSK1 = '1')        -- チャネル1割り込み発生&割り込み可
            or
            (INT_STAT0 = '1' and INT_MSK0 = '1')        -- チャネル0割り込み発生&割り込み可
        ) then
            INTA_HiZ    <= '0';                         -- INTA#ドライブ開始(アサート)
        else
            INTA_HiZ    <= '1';                         -- ハイインピーダンス状態
        end if;

        INT_IN3_flg     := INT_IN3;                     -- 現在の割り込み入力状態の保存
        INT_IN2_flg     := INT_IN2;
        INT_IN1_flg     := INT_IN1;
        INT_IN0_flg     := INT_IN0;

        -- ********** ローカルバスシーケンサ ステートマシン ********** --
        LOCAL_CURRENT_STATE := LOCAL_NEXT_STATE;

        case LOCAL_CURRENT_STATE is
            -- ********** LOCAL_IDLE時の動作 ********** --
            when LOCAL_IDLE =>                                      -- ローカルバスシーケンサ スタート指示待ち
                if (LOCAL_Bus_Start = '1' ) then                    -- ローカルバスシーケンサ スタート!
                    if (Hit_Config = '1') then                      -- コンフィグレーションサイクルヒット
                        LOCAL_NEXT_STATE    := LOCAL_CFG_ACCESS;    -- コンフィグレーションステートへ
                    end if;

                    if (Hit_Memory = '1') then                      -- メモリサイクルヒット
                        LOCAL_NEXT_STATE    := LOCAL_MEM_ACCESS;    -- メモリアクセスステートへ
                    end if;

                    if (Hit_Io = '1') then                          -- I/Oサイクルヒット
                        LOCAL_NEXT_STATE    := LOCAL_IO_ACCESS;     -- I/Oアクセスステートへ
                    end if;

                else                                                -- ローカルバスシーケンサ スタートフラグがまだならこのステートにとどまる
                    LOCAL_NEXT_STATE        := LOCAL_IDLE;

                end if;

            -- ********** LOCAL_MEM_ACCESS時の動作 ********** --
            when LOCAL_MEM_ACCESS =>
                case WAIT_Count is
                    when X"0" =>    -- ウェイトカウンタ0クロック目
                        MEM_CEn <= '0';                         -- SRAM /CE アサート
                        if (PCI_BusCommand(0) = '1') then       -- メモリライトサイクル
                            MEM_DATA_Port(31 downto 0) <= PCIAD(31 downto 0); -- ライトデータ
                            MEM_DATA_HiZ    <= '0';             -- ローカルデータバス出力方向       --px0
                        else                                    -- メモリリードサイクル
                            MEM_DATA_HiZ    <= '1';             -- ローカルデータバス入力方向
                        end if;

                        LOCAL_NEXT_STATE    := LOCAL_MEM_ACCESS ;  -- メモリアクセスはまだ終わらない

                    when X"1" =>    -- ウェイトカウンタ1クロック目
                        if (PCI_BusCommand(0) = '1') then       -- メモリライトサイクル
                            MEM_WE3n        <= C_BE_n(3);       -- バイトイネーブルを/WEに出力
                            MEM_WE2n        <= C_BE_n(2);
                            MEM_WE1n        <= C_BE_n(1);
                            MEM_WE0n        <= C_BE_n(0);
                            MEM_DATA_HiZ    <= '0';             -- ローカルデータバス出力方向       --px0
                        else                                    -- メモリリードサイクル
                            MEM_OEn <= '0';                     -- SRAM /OE アサート
                            MEM_DATA_HiZ <= '1';                -- ローカルデータバス入力方向       --px0
                        end if;

                        LOCAL_NEXT_STATE := LOCAL_MEM_ACCESS ;  -- メモリアクセスはまだ終わらない

                    when X"4" =>    -- ウェイトカウンタ4クロック目
                        if (PCI_BusCommand(0) = '1') then       -- メモリライトサイクル
                            MEM_WE3n        <= '1';             -- SRAM /WE ディセーブル
                            MEM_WE2n        <= '1';
                            MEM_WE1n        <= '1';
                            MEM_WE0n        <= '1';
                            MEM_DATA_HiZ    <= '0';             -- ローカルデータバス出力方向       --px0
                         else                                   -- メモリリードサイクル
                            PCIAD_Port(31 downto 0) <= MEM_DATA;-- SRAMデータをADバスに出力
                            MEM_OEn         <= '1';             -- SRAM /OE ディアサート
                            MEM_DATA_HiZ    <= '1';             -- ローカルデータバス入力方向       --px0
                         end if;
                            
                         LOCAL_DTACK        <= '1' ;            -- ローカルバスシーケンサ データ転送完了フラグ セット
                         LOCAL_NEXT_STATE   := LOCAL_STATE_COMP;-- メモリアクセス完了

                    when others =>    -- そのままの状態でウェイト時間が経過するのを待つ
                        LOCAL_NEXT_STATE    := LOCAL_MEM_ACCESS ;   -- メモリアクセスはまだ終わらない

                end case;

                WAIT_Count := WAIT_Count + 1;                   -- ウェイトカウント+1

            -- ********** LOCAL_IO_ACCESS時の動作 ********** --
            when LOCAL_IO_ACCESS =>
                if (PCI_BusCommand(0) = '1') then               -- ライトサイクル
                    case PCI_Address(2 downto 0) is             -- 割り込みステータスレジスタへのアクセス   --px0
                        when "000" =>                                                                       --px0
                            if (PCIAD(3) = '1') then            -- 割り込みチャネル3
                                INT_STAT3   <= '0';             -- ステータスクリア
                            end if ;

                            if (PCIAD(2) = '1') then            -- 割り込みチャネル2
                                INT_STAT2   <= '0';             -- ステータスクリア
                            end if ;

                            if (PCIAD(1) = '1') then            -- 割り込みチャネル1
                                INT_STAT1   <= '0';             -- ステータスクリア
                            end if ;

                            if (PCIAD(0) = '1') then            -- 割り込みチャネル0
                                INT_STAT0   <= '0';             -- ステータスクリア
                            end if ;

                        when "010" =>                           -- 割り込みマスクレジスタへのアクセス       --px0
                            INT_MSK3    <= PCIAD(19);           -- 割り込みマスク #3
                            INT_MSK2    <= PCIAD(18);           -- 割り込みマスク #2
                            INT_MSK1    <= PCIAD(17);           -- 割り込みマスク #1
                            INT_MSK0    <= PCIAD(16);           -- 割り込みマスク #0

                        when "100" =>                           -- doポートへのアクセス                     --px0
                             xsv_do     <= PCIAD(7 downto 0);   -- DO0..7

                        when others => null;    -- それ以外のアクセスは無視
                    end case;

                else    -- リードサイクル
                    case PCI_Address(2 downto 0) is             -- 割り込みステータスレジスタへのアクセス   --px0
                        when "000" =>                                                                       --px0
                            PCIAD_Port(31 downto  4) <= (others => '0');
                            PCIAD_Port(3)  <= INT_STAT3;        -- 割り込み3ステータス
                            PCIAD_Port(2)  <= INT_STAT2;        -- 割り込み2ステータス
                            PCIAD_Port(1)  <= INT_STAT1;        -- 割り込み1ステータス
                            PCIAD_Port(0)  <= INT_STAT0;        -- 割り込み0ステータス

                        when "010" =>                           -- 割り込みマスクレジスタへのアクセス       --px0
                            PCIAD_Port(31 downto 20) <= (others => '0');
                            PCIAD_Port(19) <= INT_MSK3;         -- 割り込み3マスク
                            PCIAD_Port(18) <= INT_MSK2;         -- 割り込み2マスク
                            PCIAD_Port(17) <= INT_MSK1;         -- 割り込み1マスク
                            PCIAD_Port(16) <= INT_MSK0;         -- 割り込み0マスク
                            PCIAD_Port(15 downto  4) <= (others => '0');

                        when "100" =>                           -- doポート読み返し                         --px0
                            PCIAD_Port(7 downto 0)      <= xsv_do;
                            PCIAD_Port(31 downto 8)     <= (others => '0');

                        when "110" =>                           -- diポートread                             --px0
                            PCIAD_Port(7 downto 0)      <= xsv_di_q0;
                            PCIAD_Port(31 downto 8)     <= (others => '0');

                        when others =>                          -- それ以外のアクセスは0を返す
                            PCIAD_Port(31 downto 0)     <= (others => '0');
                    end case;

                end if;

                LOCAL_DTACK         <= '1';
                LOCAL_NEXT_STATE    := LOCAL_STATE_COMP;

            -- ********** LOCAL_CFG_ACCESS時の動作 ********** --
            when LOCAL_CFG_ACCESS =>                            -- コンフィグレーションサイクル
                if (PCI_BusCommand(0) = '1' ) then              -- コンフィグレーションライトサイクル
                    case PCI_Address(7 downto 2) is
                        when "000001" =>                        -- コマンドレジスタ メモリイネーブル
                            if (C_BE_n(0) = '0') then
                                CFG_Cmd_Mem     <= PCIAD(1);
                                CFG_Cmd_Io      <= PCIAD(0);
                            end if;

                        when "000100" =>                        -- ベースアドレスレジスタ0
                            if (C_BE_n(3) = '0') then
                                CFG_Base_Addr0(31 downto 24) <= PCIAD(31 downto 24);
                            end if;

                        when "000101" =>                        -- ベースアドレスレジスタ1
                            if (C_BE_n(1) = '0') then
                                CFG_Base_Addr1(15 downto  8) <= PCIAD(15 downto  8);
                            end if;

                            if (C_BE_n(0) = '0') then
                                --CFG_Base_Addr1( 7 downto  2)  <= PCIAD( 7 downto  2);             --px0
                                CFG_Base_Addr1( 7 downto  3)    <= PCIAD( 7 downto  3);             --px0
                            end if;

                        when "001111" =>                        -- 割り込みラインレジスタ
                            if (C_BE_n(0) = '0') then
                                CFG_Int_Line(7 downto 0) <= PCIAD(7 downto 0);
                            end if;
                        when others => null;                    -- これ以外の値では何もしない場合でも必ず入れる
                    end case;

                else                                            -- コンフィグレーションリードサイクル
                    case PCI_Address(7 downto 2) is
                        when "000000" =>                        -- ベンダID/デバイスID
                            PCIAD_Port(31 downto 16) <= CFG_DeviceID;
                            PCIAD_Port(15 downto  0) <= CFG_VendorID;

                        when "000001" =>                        -- コマンド/ステータスレジスタ
                            PCIAD_Port(31 downto 16) <= CFG_Status;
                            PCIAD_Port(15 downto  2) <= CFG_Command(15 downto 2);
                            PCIAD_Port(1)            <= CFG_Cmd_Mem;
                            PCIAD_Port(0)            <= CFG_Cmd_Io;

                        when "000010" =>                        -- クラスコード
                            PCIAD_Port(31 downto 24) <= CFG_BaseClass;
                            PCIAD_Port(23 downto 16) <= CFG_SubClass;
                            PCIAD_Port(15 downto  8) <= CFG_ProgramIF;
                            PCIAD_Port( 7 downto  0) <= CFG_RevisionID;

                        when "000011" =>                        -- ヘッダタイプほか
                            PCIAD_Port(31 downto 24) <= (others => '0');
                            PCIAD_Port(23 downto 16) <= CFG_HeaderType;
                            PCIAD_Port(15 downto  0) <= (others => '0');

                        when "000100" =>                        -- ベースアドレスレジスタ0
                            PCIAD_Port(31 downto 24) <= CFG_Base_Addr0;
                            PCIAD_Port(23 downto  0) <= (others => '0');

                        when "000101" =>                        -- ベースアドレスレジスタ1
                            PCIAD_Port(31 downto 16) <= (others => '0');
                            --PCIAD_Port(15 downto  2) <= CFG_Base_Addr1;                           --px0
                            PCIAD_Port(15 downto  3) <= CFG_Base_Addr1;                             --px0
                            PCIAD_Port( 1 downto  0) <= "01";

                        when "001111" =>                        -- 割り込み関連レジスタ
                            PCIAD_Port(31 downto 16) <= (others => '0');
                            PCIAD_Port(15 downto  8) <= CFG_Int_Pin;
                            PCIAD_Port( 7 downto  0) <= CFG_Int_Line;

                        when others => -- その他のレジスタ
                            PCIAD_Port  <= (others => '0');     -- すべて0を返す

                    end case;

                end if;

                LOCAL_DTACK         <= '1' ;                    -- ローカルバスシーケンサ データ転送完了フラグ セット
                LOCAL_NEXT_STATE    := LOCAL_STATE_COMP;

            -- ********** LOCAL_STATE_COMP時の動作 ********** --
            when LOCAL_STATE_COMP =>                            -- ローカルバスアクセス完了
                MEM_CEn             <= '1';                     -- SRAM /CE ディアサート
                ---MEM_DATA_HiZ     <= '0';                     -- ローカルデータバス出力方向       --px0
                MEM_DATA_HiZ        <= '1';                     -- ローカルデータバス入力方向       --px0

                WAIT_Count          := (others => '0');         -- ウェイトカウンタ クリア
                LOCAL_DTACK         <= '0';                     -- ローカルバスシーケンサ データ転送完了フラグ クリア
                LOCAL_NEXT_STATE    := LOCAL_IDLE;

            -- ********************************************** --
            when others => null;    -- これ以外の値では何もしない場合でも必ず入れる

        end case;

    end if;

end process LOCAL_BUS_Seq ;


-- ************************************************************************* --
-- **********    アドレスデコーダ
-- ************************************************************************* --
-- メモリサイクルorコンフィグレーションサイクルヒット = 自分が選択されている
Hit_Device <= Hit_Memory or Hit_Config or Hit_Io;

Address_Decoder : process (
    PCI_IDSEL,          -- コンフィグレーションデバイスセレクト
    PCI_Address,        -- PCIバスアドレス
    PCI_BusCommand,     -- バスコマンド
    CFG_Base_Addr0,     -- ベースアドレスレジスタ0
    CFG_Base_Addr1,     -- ベースアドレスレジスタ1
    CFG_Cmd_Mem,        -- コンフィグレーションレジスタ メモリイネーブルビット
    CFG_Cmd_Io          -- コンフィグレーションレジスタ I/Oイネーブルビット
    )
begin

    -- メモリ空間へのアクセスアドレスとベースアドレス0が一致したか
    if (
            PCI_BusCommand(3 downto 1) = PCI_MemCycle       -- メモリサイクル
        ) and (
            PCI_Address(31 downto 24) = CFG_Base_Addr0      -- ベースアドレス0と比較
        ) and (
            CFG_Cmd_Mem = '1'                               -- コンフィグレーション コマンドレジスタ メモリイネーブルビット
        )
    then
        Hit_Memory <= '1';                                  -- メモリサイクルヒット
    else
        Hit_Memory <= '0';
    end if;

    -- I/O空間へのアクセスアドレスとベースアドレス1が一致したか
    if (
            PCI_BusCommand(3 downto 1) = PCI_IoCycle        -- I/Oサイクル
        ) and (
            CFG_Cmd_Io = '1'                                -- コンフィグレーション コマンドレジスタ I/Oイネーブルビット
        ) and (
            PCI_Address(31 downto 16)   = X"0000"           -- 上位16ビットが0か
        ) and (
            --PCI_Address(15 downto 2 ) = CFG_Base_Addr1(15 downto 2)                               --px0
            PCI_Address(15 downto 3 )   = CFG_Base_Addr1(15 downto 3)                               --px0
        )
    then
        Hit_Io <= '1';                                      -- I/Oサイクルヒット

    else
        Hit_Io <= '0';
    end if;

    -- コンフィグレーション空間へのアクセスかどうかを認識
    if (
            PCI_BusCommand(3 downto 1) = PCI_CfgCycle       -- コンフィグレーションサイクル
        ) and (
            PCI_IDSEL = '1'                                 -- 自分が選択されているか
        ) and (
            PCI_Address(10 downto 8)    = "000"             -- ファンクション番号0のみ
        ) and (
            PCI_Address(1 downto 0)     = "00"              -- タイプ0のみ
        )
    then
        Hit_Config  <= '1';                                 -- コンフィグレーションサイクルヒット
    else
        Hit_Config  <= '0';
    end if;

end process Address_Decoder;


-- ************************************************************************* --
-- **********    パリティジェネレータ
-- ************************************************************************* --

PCI_Parity_Gen : process ( PCIAD_Port, C_BE_n )
    variable temp : std_logic_vector(5 downto 0);    -- テンポラリ
begin
    -- 中間パリティ生成 --
    temp(0) := PCIAD_Port(31) xor PCIAD_Port(30) xor PCIAD_Port(29) xor PCIAD_Port(28) xor PCIAD_Port(27) xor PCIAD_Port(26);
    temp(1) := PCIAD_Port(25) xor PCIAD_Port(24) xor PCIAD_Port(23) xor PCIAD_Port(22) xor PCIAD_Port(21) xor PCIAD_Port(20);
    temp(2) := PCIAD_Port(19) xor PCIAD_Port(18) xor PCIAD_Port(17) xor PCIAD_Port(16) xor PCIAD_Port(15) xor PCIAD_Port(14);
    temp(3) := PCIAD_Port(13) xor PCIAD_Port(12) xor PCIAD_Port(11) xor PCIAD_Port(10) xor PCIAD_Port(9)  xor PCIAD_Port(8);
    temp(4) := PCIAD_Port(7)  xor PCIAD_Port(6)  xor PCIAD_Port(5)  xor PCIAD_Port(4)  xor PCIAD_Port(3)  xor PCIAD_Port(2);
    temp(5) := PCIAD_Port(1)  xor PCIAD_Port(0)  xor C_BE_n(3) xor C_BE_n(2) xor C_BE_n(1) xor C_BE_n(0);

    -- パリティ生成 --
    PAR_Port <= temp(0) xor temp(1) xor temp(2) xor temp(3) xor temp(4) xor temp(5);

end process PCI_Parity_Gen ;

end RTL;


−−−−− 本ページはここまで −−−−−