⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ms32pci.vhd

📁 pci CORES 从外国网站上弄下来的
💻 VHD
📖 第 1 页 / 共 3 页
字号:
--===================================================================--
--
--  www.OpenCores.Org - June 2000
--  This model adheres to the GNU public license  
--
-- Design units : Master device for PCI Local Bus 33 MHz 32 bits
--                  (BoardLevel Simulation model)
--                  (Entity and architecture)
--
-- File name    : MS32PCI.vhd
--
-- Purpose      : The Master device is used to simulate a master 
--                device on the PCI-Bus
--
-- Note         : This model is modelled after the PCI protocol 
--                as described in Xilinx & Altera AppNotes
--
-- Limitations  : None known
--
-- Errors       : None known
--
-- Library      : PCI_Lib.vhd
--
-- Dependencies : IEEE.Std_Logic_1164
--
-- Author       : Ovidiu Lupas
--                olupas@opencores.org
--
-- Simulator    : ModelSim EE version 5.2 on a Windows95 PC
--                ActiveVHDL 3.1 on a Windows95 PC
--===================================================================--
library ieee,work;
   use ieee.Std_Logic_1164.all;
   use work.Simulation.all;
   use std.textio.all;
   use work.PCI_Def.all;
-----------------------------------------------------------------------
--   ENTITY FOR MASTER PCI SIMULATION MODEL                          --
-----------------------------------------------------------------------
entity MS32PCI is
   generic (
      cmd_file : string := "PCI.CMD"; -- the commands file
      tdelay   : Time   := 2 ns;      -- delay time parameter
      tsetup   : Time   := 7 ns;      -- setup time to be checked
      thold    : Time   := 0 ns);     -- hold time to be checked
   port (
      -- Address, Data and Command buses (37)
      AD_Bus   : inout STD_LOGIC_VECTOR (31 downto 0);
      C_BE_Bus : inout STD_LOGIC_VECTOR (3 downto 0);
      PAR      : inout STD_LOGIC;                     
      -- Interface control signals (6)
      FRAME_N  : inout STD_LOGIC;
      TRDY_N   : in    STD_LOGIC;
      IRDY_N   : inout STD_LOGIC;
      STOP_N   : in    STD_LOGIC;
      DEVSEL_N : in    STD_LOGIC;
      IDSEL    : in    STD_LOGIC;
      -- Error reporting signals (2)
      PERR_N   : inout STD_LOGIC;
      SERR_N   : inout STD_LOGIC;
      -- Arbitration signals (2)
      REQ_N    : out   STD_LOGIC; 
      GNT_N    : in    STD_LOGIC;
      -- System signals (2)
      CLK      : in    STD_LOGIC;
      RST_N    : in    STD_LOGIC);
end MS32PCI;--================== End of entity ======================--
-----------------------------------------------------------------------
-- Architecture for Master device : PCI bus 33MHZ 32 bit configuration
-----------------------------------------------------------------------
architecture Behavior of MS32PCI is
  ---------------------------------------------------------------------
  -- Signals
  ---------------------------------------------------------------------
  signal parity_now    : Std_Logic; -- internal variable (calculate parity)
  signal parity_read   : Std_Logic; -- internal variable (parity at read)
  signal parity_flag   : Boolean;   -- internal variable (write ON/OFF on line PERR_N)
  signal PAR_READ_TEMP : Std_Logic; -- insert or no signal IRDY_N
  signal PAR_READ_FLAG : Std_Logic; -- insert or no signal IRDY_N
  ---------------------------------------------------------------------
  -- Variables
  ---------------------------------------------------------------------
  shared variable RESET : Integer;
begin --======================= Architecture ========================-- 
  ---------------------------------------------------------------------
  -- Process is used to initialize command 
  ---------------------------------------------------------------------
  RSTproc : process(RST_N)
  begin
    if not RST_N'STABLE and RST_N ='0' then
      RESET := 1;
    end if;
  end process;
  ---------------------------------------------------------------------
  -- Implements the parity generation and parity checking over the
  -- AD bus and C/BE bus.
  -- Also, generates the PERR_N signal, if the computed parity is not 
  -- equal with PAR signal, when PAR signal is generated by target
  ---------------------------------------------------------------------
  ParGen : process(CLK)
      variable PERR_N_TEMP : Std_Logic;
  begin
    if not CLK'STABLE and CLK = '0' then
       PAR <= parity_now after tdelay;      -- PAR ='1','0' or 'Z'
       PERR_N <= PERR_N_TEMP after tdelay ;
       SERR_N <= PERR_N_TEMP ;
       PAR_READ_TEMP <= parity_read ; 

       if parity_flag = true then
          PAR_READ_FLAG <= '1';
       else
          PAR_READ_FLAG <= '0';
       end if;
                  
       if PAR_READ_FLAG = '1' then   -- 
          if (PAR = PAR_READ_TEMP) then  -- MASTER sets PERR_N
             PERR_N <= '1' after tdelay;
          else 
             if PAR_READ_TEMP = 'Z' then
                PERR_N <= 'H' after tdelay;
             else          
                PERR_N <= '0' after tdelay;        
             end if;   
          end if;  
       else
         PERR_N <= 'H' after tdelay;       
       end if;       
    end if;
  end process;
  ---------------------------------------------------------------------
  -- MAIN PROCESS FOR MASTER                                                 --
  ---------------------------------------------------------------------
  MS32PCI_MAIN : process
     variable Data_array     : Data_buffer; --  data array
     variable data_last_read : Boolean;           
     variable irdy_start     : Integer; -- variable is actualize
     variable irdy_loop      : Integer;
     variable irdy_nr        : Integer; -- by command WAITC
     variable irdy_insert    : Boolean; -- assert or not IRDY_N
     ------------------------------------------------------------------
     -- Procedure is used to initialize MASTER and irdy_** variables --
     ------------------------------------------------------------------
     procedure Init is
     begin
        RESET := 0;
        AD_Bus   <= "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" ; -- Address and Data Bus
        C_BE_Bus <= "ZZZZ";            -- Command Bus
        PAR      <= 'Z';                      
        PERR_N   <= 'Z';
        REQ_N    <= 'H';
        SERR_N   <= 'H';   
         irdy_start := 0;                       -- number of IRDY state
         irdy_nr := 0;
         irdy_loop := 255;
         parity_flag <= false;
        if irdy_loop = 0 or irdy_nr = 0 then 
           irdy_insert := false;
        else
           irdy_insert := true;
        end if;          
     end Init;
     ------------------------------------------------------------------
     -- This procedure calculate parity of signals address_data(31..0) 
     -- and c_be(3..0) and return par_bit                      
     ------------------------------------------------------------------
     procedure PARITY(
        address_data : in    STD_LOGIC_VECTOR(31 downto 0); 
        c_be         : in    STD_LOGIC_VECTOR(3 downto 0);
        par_bit      : inout STD_LOGIC)   is  
     begin
        par_bit := '0';
        for I in 0 to 31 loop
            par_bit := par_bit xor address_data(I);
        end loop;

        for I in 0 to 3 loop
            par_bit := par_bit xor c_be(I);
        end loop;

        if (par_bit = 'X' or par_bit = 'U') then
          par_bit := 'Z';
        end if;
     end PARITY;
     --------------------------------------------------------------------------
     -- This procedure is used for READ_Bus and WRITE_Bus operation          --
     --------------------------------------------------------------------------
     procedure READ_WRITE(
        address : in STD_LOGIC_VECTOR(31 downto 0); -- address
        data    : in Data_buffer;                   -- data to write operation
        data_nr : in Integer;                       -- number of data DWORD(32 bit)
        bus_cmd : in STD_LOGIC_VECTOR(3 downto 0);  -- bus command
        bus_sel : in Data_Enable;                   -- C/BE lines
        rd_wr   : in STD_LOGIC)  is                 -- select read or write operation
          variable data_number : Integer;           -- number of data to read and write
          variable data_read   : Std_Logic_Vector(31 downto 0);   -- data read
          variable data_old    : Std_Logic_Vector(31 downto 0);   -- data read old
          variable stop        : Boolean;   -- internal variable (determined by STOP_N) 
          variable str8        : string(1 to 8);         
          variable Good2       : Boolean;
          variable nr_irdy     : Integer;   -- duration of IRDY pulse
          variable loop_irdy   : Integer;   -- position of IRDY pulse
          variable start_irdy  : Integer;   -- used for master-abord termination
          variable parity_temp : Std_Logic; -- internal variable
          variable trdy_stop   : Integer;   -- internal variable
          variable trdy_exit   : Boolean;   -- internal variable
     begin
        if GNT_N /= '1' then
           wait until FALLING_EDGE(CLK);           -- start cycle
        end if;   

        while (GNT_N /= '0' and GNT_N /= 'L') and (RESET = 0) loop
          wait until FALLING_EDGE(CLK);
           AD_Bus(31 downto 0) <= "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" after tdelay;
           C_BE_Bus(3 downto 0) <= "ZZZZ" after tdelay;  
           FRAME_N <= 'Z';-- after tdelay;                                  
           IRDY_N <= 'Z' after tdelay;
           parity_now <= 'Z' after tdelay;
           REQ_N <= '0' after tdelay;
        end loop;

        if (RESET = 0) then
        -- exit curent instruction if signal RST_N is active 
        -- GM
        --- acces to the bus has been granted
           data_number := data_nr;       -- number of DWORDs for transfer
           stop := false;                -- 
           start_irdy := 3;              -- 
           nr_irdy := irdy_nr;           -- actualize internal variable
           loop_irdy := irdy_loop;       -- --"--
           irdy_insert := true;          -- --"-- 
           trdy_stop := 8;               -- wait maximum 8 clock cycles for TRDY
           trdy_exit := false;

           if rd_wr = '1' then           -- READ /WRITE CYCLE
           --------------------------------------------------------------------
           -- BEGIN READ CYCLE                                               --
           --------------------------------------------------------------------
             -- address phase
             AD_Bus(31 downto 0) <= address(31 downto 0) after tdelay; -- set address  
             C_BE_Bus(3 downto 0) <= bus_cmd(3 downto 0) after tdelay; -- set command 
             FRAME_N <= '0';-- after tdelay;                                  
             IRDY_N <= '1' after tdelay;
             parity_flag <= false;
             parity_read <= 'Z' after tdelay;    
             -- calculate  parity of address cycle
             parity(address(31 downto 0), bus_cmd(3 downto 0), parity_temp);
             parity_now <= parity_temp;        

             if GNT_N'Last_Event <= tsetup then  -- GNT setup time violation ?
                report "GNT setup time violation"
                severity Warning;
             end if; 
            wait until FALLING_EDGE(CLK);        --  make turnarround cycle 
             -- GM
             REQ_N <= '1';
             -- END GM      
             IRDY_N <= '0' after tdelay;    

             AD_Bus(31 downto 0) <= "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" after tdelay;
             C_BE_Bus(3 downto 0) <= bus_sel(1) after tdelay;  
             parity_now <= 'Z';     
            wait until FALLING_EDGE(CLK);       -- end turnarround cycle              

            -- wait for DEVSEL_N = '0' 
            -- (implement MASTER-ABORT if TARGET is not responding)
               -- wait for the number of IRDY state
             while ((start_irdy > 0) and (DEVSEL_N = '1' or DEVSEL_N = 'H' or 
                DEVSEL_N = 'Z' or DEVSEL_N = 'X') ) loop
                start_irdy := start_irdy -1;   -- from the begining of read cycle
                AD_Bus(31 downto 0) <="ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" after tdelay;
                C_BE_Bus(3 downto 0) <= bus_sel(1) after tdelay;  
               wait until FALLING_EDGE(CLK);                       
             end loop;
             --- exit cycle if RST_N or STOP_N are active           
             if RESET =1 or STOP_N = '0' or STOP_N ='L' then       
                stop := true;                   -- exit cycle

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -