PCIバス用テストベンチ関連ソースファイル

pci_master_access_pac.vhd


●テストベンチ用ライブラリのソース pci_master_access_pac.vhd
-------------------------------------------------------------------------------------
-- File Name    : pci_master_access_pac.vhd
-- Function     : pci_master_access sub_program for simulation
-- Author       : F.O. (ProXi)
-- Date         : 2018/11/15
-- Company      : ProXi
-- 【備考】     : 詳細は  https://www.proxi.co.jp/technolo/pci_bus_test_bench.htm 参照
--              : 本ソースは ASIAN記法 (Attributed SIgnAl Naming)  で記述している。
--              :   詳細は https://www.proxi.co.jp/technolo/asian.htm 参照
-------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
USE ieee.numeric_std.ALL;

package pci_master_access_pac is
    -- define array
    constant MAX_DATA          : integer := 4;                  -- burst_read/write max data_no

    subtype BUS_DATA is std_logic_vector(31 downto 0);
    type    DATA_ARRAY is array (0 to (MAX_DATA-1) ) of BUS_DATA;

    subtype BEn is std_logic_vector(3 downto 0);
    type    BEn_ARRAY is array (0 to (MAX_DATA-1) ) of BEn;

    subtype STD_LOGIC_ROW is std_logic;
    type    SET_PERR_ARRAY is array (0 to (MAX_DATA-1) ) of STD_LOGIC_ROW;
    type    SET_DATA_LAST_ARRAY is array (0 to (MAX_DATA-1) ) of STD_LOGIC_ROW;

    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;

    -- define constant
    constant t_VAL          : time := 2 ns;

    -- PCI_bus Command
    constant PCI_MRD        : std_logic_vector := "0110";
    constant PCI_MRD_LINE   : std_logic_vector := "1110";       -- un_used
    constant PCI_MRD_MULTI  : std_logic_vector := "1100";       -- un_used
    constant PCI_MWR        : std_logic_vector := "0111";
    constant PCI_MWR_INVAL  : std_logic_vector := "1111";       -- un_used
    constant PCI_IORD       : std_logic_vector := "0010";
    constant PCI_IOWR       : std_logic_vector := "0011";
    constant PCI_CONFIG_RD  : std_logic_vector := "1010";
    constant PCI_CONFIG_WR  : std_logic_vector := "1011";
    constant PCI_INT_ACK    : std_logic_vector := "0000";       -- un_used
    constant PCI_SPEC_CYC   : std_logic_vector := "0001";       -- un_used
    constant PCI_DADR_CYC   : std_logic_vector := "1101";       -- un_used

    -- parity generator
    function even_parity_generator (
        ad          : std_logic_vector;
        c_be_n      : std_logic_vector;
        set_perr    : std_logic
    ) return std_logic;

    -- pci initialize
    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 configuration write
    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                           -- 
    );

    -- pci configuration read
    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
    );

    -- pci memory write
    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                           -- 
    );

    -- pci memory read
    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
    );

    -- pci io write
    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                           -- 
    );

    -- pci io read
    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
    );

    -- pci memory burst write
    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                       -- 
    );

    -- pci memory burst read
    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
    );


end pci_master_access_pac;

-------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------
package body  pci_master_access_pac is

    ---------------------------------------------------------------------------------
    -- even parity generator
    ---------------------------------------------------------------------------------
    function even_parity_generator (
        ad          : std_logic_vector;
        c_be_n      : std_logic_vector;
        set_perr    : std_logic
    ) 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;

        xc_par := xc_par xor set_perr;
        
        return (xc_par);

    end even_parity_generator;


    ---------------------------------------------------------------------------------
    -- pci master initialize
    ---------------------------------------------------------------------------------
    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                       -- 
    ) is

    begin
        v_idsel         <= (others => 'Z');
        frame_n         <= 'Z';
        ad              <= (others => 'Z');
        c_be_n          <= (others => 'Z');
        irdy_n          <= 'Z';
        par             <= 'Z';
        lock_n          <= 'Z';
        req_n           <= 'Z';
        perr_n          <= 'Z';
        serr_n          <= 'Z';
        inta_n          <= 'Z';
        intb_n          <= 'Z';
        intc_n          <= 'Z';
        intd_n          <= 'Z';

        wait for 1 ps;

    end pci_init;


    ---------------------------------------------------------------------------------
    -- pci configuration write
    ---------------------------------------------------------------------------------
    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                       -- 
    ) is

        variable xsv_c_be_n     : std_logic_vector(3 downto 0);

    begin
        wait until clk'event and clk='1';
        wait for t_VAL; 
        frame_n             <= '1';

        wait until clk'event and clk='1';
        wait for t_VAL; 
        frame_n             <= '0';
        irdy_n              <= '1';
        ad                  <= set_address;
        xsv_c_be_n          := PCI_CONFIG_WR;           -- config wr
        c_be_n              <= xsv_c_be_n;
        v_idsel             <= (others => '0'); 
        v_idsel(set_dev_no) <= '1';                     -- select device

        wait until clk'event and clk='1';
        wait for t_VAL; 
        par                 <= even_parity_generator (set_address, xsv_c_be_n, set_ad_perr); -- set address parity
        frame_n             <= '1';
        irdy_n              <= '0';
        ad                  <= set_wr_data;             -- set write data
        xsv_c_be_n          := set_be_n;                -- byte enable
        c_be_n              <= xsv_c_be_n;

        wait until (clk'event and clk='1') and (devsel_n='0') and (trdy_n='0');
        wait for t_VAL; 
        v_idsel             <= (others => 'Z');         -- negate idsel
        par                 <= even_parity_generator (set_wr_data, xsv_c_be_n, set_data_perr);  -- set data parity
        irdy_n              <= '1';
        ad                  <= (others => 'Z');
        c_be_n              <= (others => 'Z');

        wait until clk'event and clk='1';
        wait for t_VAL; 
        frame_n             <= 'Z';
        irdy_n              <= 'Z';
        par                 <= 'Z';

    end pci_config_write;


    ---------------------------------------------------------------------------------
    -- pci configuration read
    ---------------------------------------------------------------------------------
    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: set 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
    ) is

        variable xsv_c_be_n     : std_logic_vector(3 downto 0);
        variable xs_rx_par      : std_logic;

    begin
        wait until clk'event and clk='1';
        wait for t_VAL; 
        frame_n             <= '1';

        wait until clk'event and clk='1';
        wait for t_VAL; 
        frame_n             <= '0';
        irdy_n              <= '1';
        ad                  <= set_address;
        xsv_c_be_n          := PCI_CONFIG_RD;           -- config read
        c_be_n              <= xsv_c_be_n;
        v_idsel             <= (others => '0'); 
        v_idsel(set_dev_no) <= '1';                     -- select device
        perr_n              <= 'Z';

        wait until clk'event and clk='1';
        wait for t_VAL; 
        par                 <= even_parity_generator (set_address, xsv_c_be_n, set_ad_perr); -- set address parity
        frame_n             <= '1';
        irdy_n              <= '0';
        ad                  <= (others => 'Z');         -- negate ad
        xsv_c_be_n          := set_be_n;                -- byte enable
        c_be_n              <= xsv_c_be_n;

        wait until clk'event and clk='1';
        par                 <= 'Z';

        wait until (clk'event and clk='1') and (devsel_n='0') and (trdy_n='0');
        xs_rx_par           := even_parity_generator (ad, xsv_c_be_n, '0');    -- generate receive data parity
        sv_read_data        <= ad;                      -- latch read_data
        irdy_n              <= '1';
        c_be_n              <= (others => 'Z');

        wait until clk'event and clk='1';
        v_idsel             <= (others => 'Z');         -- idsel Hi_Z
        frame_n             <= 'Z';
        irdy_n              <= 'Z';
        if (par /= xs_rx_par)  then                     -- parity check
            perr_n          <= '0';
        else
            perr_n              <= 'Z';
        end if;

        wait until clk'event and clk='1';
        wait for t_VAL; 
        perr_n              <= 'Z';

    end pci_config_read;


    ---------------------------------------------------------------------------------
    -- pci memory write
    ---------------------------------------------------------------------------------
    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                       -- 
    ) is

        variable xsv_c_be_n     : std_logic_vector(3 downto 0);

    begin
        wait until clk'event and clk='1';
        wait for t_VAL; 
        frame_n             <= '1';

        wait until clk'event and clk='1';
        wait for t_VAL; 
        frame_n             <= '0';
        irdy_n              <= '1';
        ad                  <= set_address;
        xsv_c_be_n          := PCI_MWR;                 -- memory wr
        c_be_n              <= xsv_c_be_n;

        wait until clk'event and clk='1';
        wait for t_VAL; 
        par                 <= even_parity_generator (set_address, xsv_c_be_n, set_ad_perr); -- set address parity
        frame_n             <= '1';
        irdy_n              <= '0';
        ad                  <= set_wr_data;             -- set write data
        xsv_c_be_n          := set_be_n;                -- set byte enable size
        c_be_n              <= xsv_c_be_n;

        wait until (clk'event and clk='1') and (devsel_n='0') and (trdy_n='0');
        wait for t_VAL; 
        par                 <= even_parity_generator (set_wr_data, xsv_c_be_n, set_data_perr); -- set data parity
        irdy_n              <= '1';
        ad                  <= (others => 'Z');
        c_be_n              <= (others => 'Z');

        wait until clk'event and clk='1';
        wait for t_VAL; 
        frame_n             <= 'Z';
        irdy_n              <= 'Z';
        par                 <= 'Z';

    end pci_memory_write;


    ---------------------------------------------------------------------------------
    -- pci memory read
    ---------------------------------------------------------------------------------
    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
    ) is

        variable xsv_c_be_n     : std_logic_vector(3 downto 0);
        variable xs_rx_par      : std_logic;

    begin
        wait until clk'event and clk='1';
        wait for t_VAL; 
        frame_n             <= '1';

        wait until clk'event and clk='1';
        wait for t_VAL; 
        frame_n             <= '0';
        irdy_n              <= '1';
        ad                  <= set_address;
        xsv_c_be_n          := PCI_MRD;                 -- memory read
        c_be_n              <= xsv_c_be_n;
        perr_n              <= 'Z';

        wait until clk'event and clk='1';
        wait for t_VAL; 
        par                 <= even_parity_generator (set_address, xsv_c_be_n, set_ad_perr); -- set address parity
        frame_n             <= '1';
        irdy_n              <= '0';
        ad                  <= (others => 'Z');         -- negate ad
        xsv_c_be_n          := set_be_n;                -- byte_enable
        c_be_n              <= xsv_c_be_n;

        wait until clk'event and clk='1';
        wait for t_VAL; 
        par                 <= 'Z';

        wait until (clk'event and clk='1') and (devsel_n='0') and (trdy_n='0');
        xs_rx_par           := even_parity_generator (ad, xsv_c_be_n, '0');                 -- generate receive data parity
        sv_read_data        <= ad;                      -- latch read_data
        irdy_n              <= '1';
        c_be_n              <= (others => 'Z');

        wait until clk'event and clk='1';
        frame_n             <= 'Z';
        irdy_n              <= 'Z';
        if (par /= xs_rx_par)  then                      -- parity check
            perr_n          <= '0';
        else
            perr_n              <= 'Z';
        end if;

        wait until clk'event and clk='1';
        perr_n              <= 'Z';
    end pci_memory_read;    


    ---------------------------------------------------------------------------------
    -- pci io write
    ---------------------------------------------------------------------------------
    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                       -- 
    ) is

        variable xsv_c_be_n     : std_logic_vector(3 downto 0);

    begin
        wait until clk'event and clk='1';
        frame_n             <= '1';

        wait until clk'event and clk='1';
        wait for t_VAL; 
        frame_n             <= '0';
        irdy_n              <= '1';
        ad                  <= set_address;
        xsv_c_be_n          := PCI_IOWR;                -- io wr
        c_be_n              <= xsv_c_be_n;

        wait until clk'event and clk='1';
        wait for t_VAL; 
        par                 <= even_parity_generator (set_address, xsv_c_be_n, set_ad_perr); -- set address parity
        frame_n             <= '1';
        irdy_n              <= '0';
        ad                  <= set_wr_data;             -- set write data
        xsv_c_be_n          := set_be_n;                -- set byte enable size
        c_be_n              <= xsv_c_be_n;

        wait until (clk'event and clk='1') and (devsel_n='0') and (trdy_n='0');
        wait for t_VAL; 
        par                 <= even_parity_generator (set_wr_data, xsv_c_be_n, set_data_perr); -- set data parity
        irdy_n              <= '1';
        ad                  <= (others => 'Z');
        c_be_n              <= (others => 'Z');

        wait until clk'event and clk='1';
        wait for t_VAL; 
        frame_n             <= 'Z';
        irdy_n              <= 'Z';
        par                 <= 'Z';

    end pci_io_write;


    ---------------------------------------------------------------------------------
    -- pci io read
    ---------------------------------------------------------------------------------
    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
    ) is

        variable xsv_c_be_n     : std_logic_vector(3 downto 0);
        variable xs_rx_par      : std_logic;

    begin
        wait until clk'event and clk='1';
        wait for t_VAL; 
        frame_n             <= '1';

        wait until clk'event and clk='1';
        wait for t_VAL; 
        frame_n             <= '0';
        irdy_n              <= '1';
        ad                  <= set_address;
        xsv_c_be_n          := PCI_IORD;                -- io read
        c_be_n              <= xsv_c_be_n;
        perr_n              <= 'Z';

        wait until clk'event and clk='1';
        wait for t_VAL; 
        par                 <= even_parity_generator (set_address, xsv_c_be_n, set_ad_perr); -- set address parity
        frame_n             <= '1';
        irdy_n              <= '0';
        ad                  <= (others => 'Z');         -- negate ad
        xsv_c_be_n          := set_be_n;                -- byte_enable
        c_be_n              <= xsv_c_be_n;

        wait until clk'event and clk='1';
        wait for t_VAL; 
        par                 <= 'Z';

        wait until (clk'event and clk='1') and (devsel_n='0') and (trdy_n='0');
        xs_rx_par           := even_parity_generator (ad, xsv_c_be_n, '0');                 -- generate receive data parity
        sv_read_data        <= ad;                      -- latch read_data
        irdy_n              <= '1';
        ad                  <= (others => 'Z');         -- negate ad
        c_be_n              <= (others => 'Z');

        wait until clk'event and clk='1';
        frame_n             <= 'Z';
        irdy_n              <= 'Z';
        if (par /= xs_rx_par)  then                      -- parity check
            perr_n          <= '0';
        else
            perr_n          <= 'Z';
        end if;

        wait until clk'event and clk='1';
        perr_n              <= 'Z';

    end pci_io_read;


    ---------------------------------------------------------------------------------
    -- pci memory burst write
    ---------------------------------------------------------------------------------
    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

    ) is
        variable    xsv_c_be_n      : std_logic_vector(3 downto 0);
        variable    xs_tmp_par      : std_logic;
        variable    xs_exit_flg     : std_logic := '0';

    begin
        -- create array
        wait until clk'event and clk='1';
        wait for t_VAL;
        frame_n             <= '1';

        -- address set
        wait until clk'event and clk='1';
        wait for t_VAL;
        frame_n     <= '0';
        irdy_n      <= '1';

        xsv_c_be_n  := PCI_MWR;                 
        c_be_n      <= xsv_c_be_n;

        --ad        <= set_address(31 downto 2) & "00";                                                     -- when make address 32bits boundery
        --xs_tmp_par  := even_parity_generator (set_address(31 downto 2) & "00", xsv_c_be_n, set_ad_perr);  --   set address parity
        ad          <= set_address;
        xs_tmp_par  := even_parity_generator (set_address, xsv_c_be_n, set_ad_perr);                        --   set address parity

        xs_exit_flg := '0';

        wait until clk'event and clk='1';
        wait for t_VAL;

        -- data set
        for i in 0 to (MAX_DATA -1) loop
            par         <= xs_tmp_par;
            irdy_n      <= '0';
            ad          <= SET_DATA_ARRAY(I).WR_DATA;                                                       -- set write data
            c_be_n      <= SET_DATA_ARRAY(i).BEn;
            xs_tmp_par  := even_parity_generator (SET_DATA_ARRAY(i).WR_DATA, SET_DATA_ARRAY(i).BEn, SET_DATA_ARRAY(i).PERR ); -- next parity

            if (i >= (MAX_DATA -1) ) then                                                                   -- when i = max
                xs_exit_flg := '1';
                frame_n     <= '1';                                                                         -- fail safe
            elsif (SET_DATA_ARRAY(i).LAST = '1') then                                                       -- for SET_DATA_ARRAY(0).LAST ='1' (only one_data) 
                    frame_n     <= '1';
                    xs_exit_flg := '1';
            end if;

            wait until (clk'event and clk='1') and (devsel_n='0') and (trdy_n='0');
            wait for t_VAL;
            exit when (xs_exit_flg = '1');

            if (i <= (MAX_DATA -2)) then                        -- normal behavior
                if (SET_DATA_ARRAY(i +1).LAST = '1') then
                    frame_n     <= '1';
                end if;
            else                                                -- when i = max
                frame_n     <= '1';                             -- fail safe
            end if;
        end loop;

        par         <= xs_tmp_par;
        irdy_n      <= '1';
        ad          <= (others => 'Z');
        c_be_n      <= (others => 'Z');

        wait until clk'event and clk='1';
        wait for t_VAL;
        frame_n     <= 'Z';
        irdy_n      <= 'Z';
        par         <= 'Z';

    end pci_memory_burst_write;

    ---------------------------------------------------------------------------------
    -- pci memory burst read
    ---------------------------------------------------------------------------------
    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
    ) is
        variable    xsv_c_be_n      : std_logic_vector(3 downto 0);
        variable    xs_rx_par       : std_logic;
        variable    xs_tmp_par      : std_logic;
        variable    xs_exit_flg     : std_logic := '0';
        variable    xsva_read_data  : DATA_ARRAY;

    begin
        wait until clk'event and clk='1';
        wait for t_VAL; 
        frame_n        <= '1';

        wait until clk'event and clk='1';
        wait for t_VAL; 
        frame_n         <= '0';
        irdy_n          <= '1';

        xsv_c_be_n      := PCI_MRD;                 
        c_be_n          <= xsv_c_be_n;

        --ad            <= set_address(31 downto 2) & "00";                                                     -- when make address 32bits boundery
        --xs_tmp_par    := even_parity_generator (set_address(31 downto 2) & "00", xsv_c_be_n, set_ad_perr);    --   set address parity
        ad              <= set_address(31 downto 0);
        xs_tmp_par      := even_parity_generator (set_address, xsv_c_be_n, set_ad_perr);                        --   set address parity

        wait until clk'event and clk='1';
        wait for t_VAL;
        if (set_data_no <= 1) then
            frame_n     <= '1';
        end if;

        par         <= xs_tmp_par;
        irdy_n      <= '0';
        ad          <= (others => 'Z');                 -- negate ad
        c_be_n      <= set_be_n_array(0);               -- byte_enable

        wait until clk'event and clk='1';
        wait for t_VAL;
        par                 <= 'Z';
        xs_exit_flg := '0';

        -- data read
        for i in 0 to (set_data_no -1) loop
            exit when (xs_exit_flg = '1');
            
            wait until (clk'event and clk='1') and (devsel_n='0') and (trdy_n='0');
            xsva_read_data(i)   := ad;                      -- latch read_data
            xs_rx_par           := even_parity_generator (xsva_read_data(i), set_be_n_array(i), '0');    -- generate receive data parity
            sva_read_data(i)    <= xsva_read_data(i);

            if (i >= (set_data_no -1) ) then
                xs_exit_flg := '1';
                c_be_n      <= (others => 'Z');
                irdy_n      <= '1';
            end if;

            if (set_data_no >= 2) then
                if (i = (set_data_no-2) ) then
                    frame_n     <= '1';
                end if;
            end if;
        end loop;

        wait until clk'event and clk='1';
        frame_n             <= 'Z';
        irdy_n              <= 'Z';
        if (par /= xs_rx_par)  then                      -- parity check
            perr_n          <= '0';
        else
            perr_n              <= 'Z';
        end if;

        wait until clk'event and clk='1';
        perr_n              <= 'Z';
    end pci_memory_burst_read;


end pci_master_access_pac;


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