OpenCores
URL https://opencores.org/ocsvn/pci_core/pci_core/trunk

Subversion Repositories pci_core

[/] [pci_core/] [trunk/] [vhdl_behav/] [Ms32pci.vhd] - Rev 11

Go to most recent revision | Compare with Previous | Blame | View Log

--===================================================================--
--
--  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
             end if;
 
             if DEVSEL_N'Last_Event <= tsetup then    
                report "DEVSEL_N  setup time violation"
                   severity Warning;
             end if; 
 
             --- inset IRDY_N if loop_irdy =1 and nr_irdy >1   
             if loop_irdy =1 then
                while  (nr_irdy > 1) loop
                   IRDY_N <='1' after tdelay;    
                   nr_irdy   := nr_irdy -1 ;
                  wait until FALLING_EDGE(CLK);                       
                end loop;  
                IRDY_N <='0' after tdelay;    
             end if;          
 
             -- terminate cycle because DEVSEL_N is anactive 
             -- (implement command MASTER-ABORT TERMINATION )   
             if start_irdy = 0 then   -- terminate cycle
                stop := true;
                FRAME_N <='1'; -- after tdelay;                                  
             end if;
 
             --   wait until FALLING_EDGE(CLK);                       
             -- repeat until all data are read or  STOP_N ='0'
             while ((data_number > 0) and (stop = false)) loop  -- read cycle  
                parity_flag <= true;
                data_number := data_number -1;
                parity_flag <= true;
                data_read := data(data_nr - data_number);
                if data_number = 0 then
                   C_BE_Bus(3 downto 0) <=bus_sel(data_nr) after tdelay; 
                   data_read := data(data_nr);      
                else 
                   C_BE_Bus(3 downto 0) <=bus_sel(data_nr - data_number+1) after tdelay;
                   data_read := data(data_nr - data_number);
                end if; 
 
                parity_flag <= true;
                if data_number =0 then
                   FRAME_N <='1';-- after tdelay;                           
                end if;
 
                -- 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 
                   irdy_insert := false;
                end if;
 
                if irdy_insert = true and (data_nr - data_number) = loop_irdy  then
                   -- insert IRDY ='1' if insert_trdy =true 
                   while nr_irdy > 1 loop
                      nr_irdy   := nr_irdy -1 ;
                      IRDY_N <= '1' after tdelay;    -- insert IRDY
                      -- 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
                         nr_irdy := 1;
                      end if;                    
                     wait until FALLING_EDGE(CLK);
                   end loop; -- end loop nr_irdy
                end if; -- end if irdy_insert                         
 
                --  IRDY_N <= '0' after tdelay; 
                if data_number = 0 then
                   IRDY_N <= '0' after tdelay;       
                end if;        
               wait until RISING_EDGE(CLK);
 
                if TRDY_N'Last_Event <= tsetup then    -- end of cycle
                   report "TRDY_N setup time violation"
                      severity Warning;
                end if;
 
                -- wait for TRDY_N = '0' (maxim 8 clock pulse)       
                while TRDY_N = '1' and trdy_exit = false loop      
                   wait until RISING_EDGE(CLK);
                   -- wait maxim 8 clock pulse if TRDY is asserted
                    trdy_stop := trdy_stop -1;   
                    if trdy_stop = 0 then
                       stop := true;
                       report "Target is not responding "
                          severity Warning;
                       FRAME_N <= '1';-- after tdelay;  
                       IRDY_N <= '1' after tdelay;
                       trdy_exit := true;
                    end if; 
 
                    -- 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
                       trdy_exit := true;
                    end if;                         
                end loop; -- end loop TRDY_N=1                  
 
                Vec2Hex (data_read,str8,Good2);
                report "        EXPECTED DATA= "&str8 &"";  -- display expected data   
 
                Vec2Hex (AD_Bus,str8,Good2);
                report "        READ DATA= "&str8 &"";      -- display receive data
 
                if  AD_Bus'Last_Event <= tsetup then        -- end of cycle
                    report "AD_BUS setup time violation"
                       severity Warning;
                end if;
 
                if ((data_number >0) and (stop =false)) then
                   wait until FALLING_EDGE(CLK);
                end if;
 
               wait for thold;
                if AD_Bus'Last_Event <= thold then    -- end of cycle
                   report "AD_Bus hold time violation"
                      severity Warning;
                end if;             
             end loop; -- end loop data_number
 
             if RESET =1 or STOP_N ='0' or STOP_N ='L' then      
                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 <= 'H' after tdelay;
                parity_flag <= false;
             end if;                         
           else
           --------------------------------------------------------------------
           -- BEGIN WRITE CYCLE                                              --
           --------------------------------------------------------------------
              -- adress phase 
              parity_flag <= false;
              nr_irdy := nr_irdy;
              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_read <= 'Z';      
              parity(address(31 downto 0), bus_cmd(3 downto 0), parity_temp); -- calculate  parity of address cycle
              parity_now <= parity_temp after tdelay;
             wait until FALLING_EDGE(CLK);
              -- end adress phase                
 
              REQ_N <='1';
 
              parity_flag <= false;
              IRDY_N <= '0' after tdelay;    
              --  wait for 1 ns;
              -- wait for DEVSEL_N = '0' 
              -- (implement command MASTER-ABORT TERMINATION if TARGET not respond)
              while ((start_irdy > 0) and (DEVSEL_N ='H' or DEVSEL_N ='Z' or DEVSEL_N ='X') ) loop           -- wait for the number of IRDY state
                 start_irdy := start_irdy -1;        -- from the begining of read cycle  
                wait until FALLING_EDGE(CLK);
              end loop;
 
              -- if device not respond then exits the write command
              if start_irdy = 0 then   -- terminate cycle
                 stop := true;
                 FRAME_N <= '1';-- after tdelay;                                  
              end if;
 
              if DEVSEL_N'Last_Event <= tsetup then    
                 report "DEVSEL_N  setup time violation"
                    severity Warning;
              end if; 
 
              while ((data_number >0) and (stop =false)) loop
                 -- data phase
                 data_number := data_number -1;       
                 AD_Bus(31 downto 0) <= data(data_nr - data_number) after tdelay;      -- set DATA
                 C_BE_Bus(3 downto 0) <= bus_sel(data_nr - data_number) after tdelay;  -- set BE#s
                 IRDY_N <= '0' after tdelay;
                 parity(data(data_nr - data_number), bus_sel(data_nr - data_number), parity_temp); -- calculate  parity
                 parity_now <= parity_temp after tdelay;
                 -- end data phase
 
                 if data_number = 0 then
                    FRAME_N <= '1';-- after tdelay;
                 end if;    
 
                 -- exit cycle if RST_N,GNT_N or STOP_N are active
                 if RESET = 1 or STOP_N= '0' or STOP_N = 'L' then       
                    stop := true;                                -- exit cycle
                 end if;
 
                wait until RISING_EDGE(CLK);
 
                 if TRDY_N'Last_Event <= tsetup then    -- end of cycle
                    report "TRDY_N setup time violation"
                       severity Warning;
                 end if;
 
                 -- wait for TRDY_N ='0'       
                 while TRDY_N ='1' and   trdy_exit = false loop
                    wait until RISING_EDGE(CLK); 
                     -- wait maxim 8 clock pulse if TRDY is asserted
                     trdy_stop := trdy_stop -1;
                     if trdy_stop = 0 then
                        stop := true;
                        report "Target is not responding "
                           severity Warning;
                        FRAME_N <= '1';-- after tdelay;  
                        IRDY_N <= '1' after tdelay;
                        trdy_exit := true;                                
                     end if;                       
 
                     -- exit cycle if RST_N,GNT_N or STOP_N are active
                     if RESET = 1 or STOP_N = '0' or STOP_N = 'L' then       
                        stop := true;                       -- exit cycle
                        trdy_exit := true;
                     end if;
                 end loop; -- end loop TRDY=1            
 
                 if ((data_number > 0)  and (stop = false)) then
                    wait until FALLING_EDGE(CLK); -- synchronize with PCICLK
                 end if;
                 -- insert IRDY_N                               
                 if irdy_insert = true and (data_nr -data_number) = loop_irdy  
                            and data_number >0 and (stop =false) then 
                    while nr_irdy > 1 loop  
                       IRDY_N <='1' after tdelay;                                                                                    
                       nr_irdy := nr_irdy -1 ;   
                       if nr_irdy > 0 then
                          if data_number > 0 then
                             C_BE_Bus(3 downto 0) <=bus_sel(data_nr - data_number +1) after tdelay;  -- set BE#s
                             parity(data(data_nr - data_number), bus_sel(data_nr - data_number+1), parity_temp); -- calculate  parity        
                             parity_now <= parity_temp after tdelay;          
                          end if;
                       wait until FALLING_EDGE(CLK);
                       end if;
 
                       if RESET = 1 or STOP_N = '0' or STOP_N = 'L' then       
                          stop := true;                               -- exit cycle
                          nr_irdy := 1;
                       end if;                   
                    end loop;  -- end loop nr_irdy                                 
                 end if;         
                 report "        WRITE DATA= "&str8 &"";      -- display write data
            end loop; -- end loop start_irdy > 0 ...
 
            if RESET = 1 or STOP_N = '0' or STOP_N = 'L' then      
               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 <= 'H' after tdelay;
               parity_flag <= false;
            end if;                                    
          end if; -- end rd_wr = '1'
       end if; -- if RST_N ='0' then
     end READ_WRITE;
     --------------------------------------------------------------------------
     --  Procedure implement instruction WRSW                                --
     --------------------------------------------------------------------------
     -- Writes single DWORD to memory space!
     procedure WRSW(
        data        : in    Data_buffer;
        address     : inout STD_LOGIC_VECTOR(31 downto 0);
        data_number : in    Integer;
        bus_sel     : in    Data_Enable) is
        variable   bus_cmd  : STD_LOGIC_VECTOR(3 downto 0);
        variable str8,str_8 : string(1 to 8);
        variable Good2      : Boolean;
     begin
        bus_cmd := "0111";
        address(1 downto 0) := "00";
        Vec2Hex (data(1),str8,Good2);
        Vec2Hex (address,str_8,Good2);      
        report "Write single DWORD to memory space! Address : "&str_8;
        READ_WRITE(address,data,1,bus_cmd,bus_sel,'0');
     end WRSW;
     --------------------------------------------------------------------------
     --  Procedure implement instruction RDSW                                --
     --------------------------------------------------------------------------
     --  Reads single DWORD from memory space!
     procedure RDSW(
        data        : in    Data_buffer;
        address     : inout STD_LOGIC_VECTOR(31 downto 0);
        data_number : in    Integer;
        bus_sel     : in    Data_Enable)   is
        variable bus_cmd    : STD_LOGIC_VECTOR(3 downto 0);
        variable read_data  : Data_buffer;
        variable str8,str_8 : string(1 to 8);
        variable Good2      : Boolean;
     begin
        bus_cmd := "0110";
        address(1 downto 0) := "00";  
        Vec2Hex (address,str_8,Good2);
        report "Read single DWORD from memory space! Address : "&str_8 ;
        READ_WRITE(address,data,1,bus_cmd,bus_sel,'1');
     end RDSW;
     --------------------------------------------------------------------------
     -- Procedure implements instruction WRMW                                --
     --------------------------------------------------------------------------
     -- Writes multiple DWORDs to memory space - burst mode
     procedure WRMW(
        data        : in    Data_buffer;
        address     : inout STD_LOGIC_VECTOR(31 downto 0);
        data_number : in    Integer;
        bus_sel     : in    Data_Enable)    is
        variable   bus_cmd  : STD_LOGIC_VECTOR(3 downto 0);
        variable str8,str_8 : string(1 to 8);
        variable Good2      : Boolean;
     begin
        bus_cmd := "1111";
        address(1 downto 0) := "10";
        Vec2Hex (address,str_8,Good2);
        report "Write multiple DWORDs to memory space! Address : "&str_8 ;
        READ_WRITE(address,data,data_number,bus_cmd,bus_sel,'0');    
     end WRMW;
     --------------------------------------------------------------------------
     -- Procedure implements instruction RDMW                                --
     --------------------------------------------------------------------------
     -- Reads multiple DWORDs from memory space - burst mode
     procedure RDMW(
        data        : in    Data_buffer;
        address     : inout STD_LOGIC_VECTOR(31 downto 0);
        data_number : in    Integer;
        bus_sel     : in    Data_Enable)   is
        variable bus_cmd    : STD_LOGIC_VECTOR(3 downto 0);
        variable read_data  : Data_buffer;
        variable str8,str_8 : string(1 to 8);
        variable Good2      : Boolean;
     begin
        bus_cmd := "1100";
        address(1 downto 0) := "10";
        Vec2Hex (address,str_8,Good2);
        report "Read multiple DWORDs from memory space! Address : "&str_8;
        READ_WRITE(address,data,data_number,bus_cmd,bus_sel,'1'); 
     end RDMW;
     --------------------------------------------------------------------------
     -- Procedure implements instruction RDML                                --
     --------------------------------------------------------------------------
     -- Reads multiple DWORDs from memory space!
     procedure RDML(
        data        : in    Data_buffer;
        address     : inout STD_LOGIC_VECTOR(31 downto 0);
        data_number : in    Integer;
        bus_sel     : in    Data_Enable)   is
        variable   bus_cmd: STD_LOGIC_VECTOR(3 downto 0);
        variable   read_data: Data_buffer;
        variable str8,str_8 : string(1 to 8);
        variable Good2       : Boolean;
     begin
        bus_cmd := "1110";
        address(1 downto 0) := "00";
        Vec2Hex (address,str_8,Good2);
        report "Reads multiple DWORDs from memory space! Address : "&str_8;
        READ_WRITE(address,data,data_number,bus_cmd,bus_sel,'1');      
     end RDML;
     --------------------------------------------------------------------------
     -- Procedure implements instruction WCFG                                --
     --------------------------------------------------------------------------
     -- writes configuration
     procedure WCFG(
        data        : in    Data_buffer;
        address     : inout STD_LOGIC_VECTOR(31 downto 0);
        data_number : in    Integer;
        bus_sel     : in    Data_Enable)   is
        variable bus_cmd    : STD_LOGIC_VECTOR(3 downto 0);
        variable read_data  : Data_buffer;
        variable str8,str_8 : string(1 to 8);
        variable Good2      : Boolean;
     begin
        bus_cmd :="1011";
        address(1 downto 0) :="00";              -- linear incrementing
        Vec2Hex (address,str_8,Good2);
        report "Configuration write! Address : "&str_8;
        READ_WRITE(address,data,data_number,bus_cmd,bus_sel,'0');  
     end WCFG;
     --------------------------------------------------------------------------
     -- Procedure implements instruction RCFG                                --
     --------------------------------------------------------------------------
     -- reads configuration
     procedure RCFG(
        data        : in    Data_buffer;
        address     : inout STD_LOGIC_VECTOR(31 downto 0);
        data_number : in    Integer;
        bus_sel     : in    Data_Enable)   is
        variable bus_cmd    : STD_LOGIC_VECTOR(3 downto 0);
        variable read_data  : Data_buffer;
        variable str8,str_8 : string(1 to 8);
        variable Good2      : Boolean;
     begin
        bus_cmd :="1010";
        address(1 downto 0) :="00";
        Vec2Hex (address,str_8,Good2);
        report "Configuration read ! Address : "&str_8; 
        READ_WRITE(address,data,data_number,bus_cmd,bus_sel,'1');      
     end RCFG;
     --------------------------------------------------------------------------
     -- Procedure implements instruction WRIO                                --
     --------------------------------------------------------------------------
     -- writes data to IO port
     procedure WRIO(
        data        : in Data_buffer;
        address     : inout STD_LOGIC_VECTOR(31 downto 0);
        data_number : in Integer;
        bus_sel     : in Data_Enable)    is
        variable bus_cmd    : STD_LOGIC_VECTOR(3 downto 0);
        variable read_data  : Data_buffer;
        variable str8,str_8 : string(1 to 8);
        variable Good2      : Boolean;
     begin
        bus_cmd := "0011";
        address(1 downto 0) := "00";   
        Vec2Hex (address,str_8,Good2);
        report "Write DWORD to I/O space! Address : "&str_8;  
        READ_WRITE(address,data,data_number,bus_cmd,bus_sel,'0'); 
     end WRIO;
     --------------------------------------------------------------------------
     -- Procedure implements instruction RDIO                                --
     --------------------------------------------------------------------------
     -- reads data from IO port
     procedure RDIO(
        data        : in    Data_buffer;
        address     : inout STD_LOGIC_VECTOR(31 downto 0);
        data_number : in    Integer;
        bus_sel     : in    Data_Enable)   is
        variable bus_cmd    : STD_LOGIC_VECTOR(3 downto 0);
        variable read_data  : Data_buffer;
        variable str8,str_8 : string(1 to 8);
        variable Good2      : Boolean;
     begin
        bus_cmd :="0010";
        address(1 downto 0) :="00";
        Vec2Hex (address,str_8,Good2);
        report "Read DWORD from memory space! Address : "&str_8;  
        READ_WRITE(address,data,data_number,bus_cmd,bus_sel,'1');   
     end RDIO;
     --------------------------------------------------------------------------
     -- Procedure implements instruction WAIT                                --
     --------------------------------------------------------------------------
     -- waits 
     procedure CWAT(
        data        : in Data_buffer;
        address     : inout STD_LOGIC_VECTOR(31 downto 0);
        data_number : in Integer;
        bus_sel     : in Data_Enable)   is  
        variable bus_cmd    : STD_LOGIC_VECTOR(3 downto 0);
        variable str8,str_8 : string(1 to 8);
        variable Good2      : Boolean;
        variable byte7_6,byte5,byte4,byte3_2,byte1,byte0 : Integer;
        variable Char7_6,Char5,Char4,Char3_2,Char1,Char0 : Std_Logic_Vector(7 downto 0);
     begin
        Char7_6 := data(1)(31 downto 24);
        irdy_loop := Byte2Int(Char7_6) ;	
        Char5 := "0000" & data(1)(23 downto 20);
        irdy_nr := Byte2Int(Char5) + 1;
        Char4 := "0000" & data(1)(19 downto 16);
        irdy_start := Byte2Int(Char4);
        bus_cmd := "0001";
        if irdy_loop = 0 or irdy_nr = 0 then 
           irdy_insert := false;
        else
           irdy_insert := true;
        end if;
        READ_WRITE(address,data,data_number,bus_cmd,bus_sel,'0'); 
     end CWAT;
     --------------------------------------------------------------------------
     -- Procedure implements instruction EXIT                                --
     --------------------------------------------------------------------------
     -- ends the Master's activity by placing in HighZ all the lines
     procedure ABRT is  
     begin
        wait until FALLING_EDGE(CLK);    -- synchro cycle 
         Init;
        wait;
     end ABRT;
     --------------------------------------------------------------------------
     -- Procedure implements the commands file parser and sequencer          --
     --------------------------------------------------------------------------
     procedure Main_case is     
         variable Commands    : CommandArray(1 to 100);     
         variable NumCommands : Natural;
         variable Good        : Boolean;
         constant HeaderMsg   : String         := "Main process:";
         constant MsgSeverity : Severity_Level := Failure;
         variable ErrFlag     : Boolean;
         variable PC          : Integer;    
     begin
         -- Read/Parse the commands file
         FileParser (cmd_file,Commands,NumCommands,ErrFlag);
         data_last_read :=  FALSE;
         if ErrFlag then
            report HeaderMsg&"Errors found in COMMAND file. Execute halts!!!"
               severity Warning;
         else
            PC := 0;
           wait until RST_N = '1';
            while PC < NumCommands Loop
               if RESET = 1 then
                  RESET := 0;
                  PC := 0;
               end if;
               while RST_N = '0' loop         -- RESET signal is active
                  PC := 0;                    -- if RST_N ='0' restart simulation
                  REQ_N <= 'H';               -- request is tri-stated
                 wait until Rising_Edge(CLK); -- synchro wait
               end loop;
               if STOP_N = '0' then        
                  report HeaderMsg&"Wait until signal STOP_N ='0' !";
                 wait until STOP_N = '1';
               end if;
               REQ_N <= '0';
 
               PC := PC + 1;          
               case Commands(pc).command is
                  when "WRSW" =>
                        WRSW(Commands(pc).data,Commands(PC).addr,Commands(pc).data_nr,Commands(pc).Enable);
                  when "RDSW" =>
                        RDSW(Commands(pc).data,Commands(PC).addr,Commands(pc).data_nr,Commands(pc).Enable);
                  when "WRMW" =>
                        WRMW(Commands(pc).data,Commands(PC).addr,Commands(pc).data_nr,Commands(pc).Enable);
                  when "RDMW" =>
                        RDMW(Commands(pc).data,Commands(PC).addr,Commands(pc).data_nr,Commands(pc).Enable);
                  when "RDML" =>
                        RDML(Commands(pc).data,Commands(PC).addr,Commands(pc).data_nr,Commands(pc).Enable);
                  when "WCFG" =>
                        WCFG(Commands(pc).data,Commands(PC).addr,Commands(pc).data_nr,Commands(pc).Enable);
                  when "RCFG" =>
                        RCFG(Commands(pc).data,Commands(PC).addr,Commands(pc).data_nr,Commands(pc).Enable);
                  when "WRIO" =>
                        WRIO(Commands(pc).data,Commands(PC).addr,Commands(pc).data_nr,Commands(pc).Enable);
                  when "RDIO" =>
                        RDIO(Commands(pc).data,Commands(PC).addr,Commands(pc).data_nr,Commands(pc).Enable);
                  when "CWAT" =>
                        CWAT(Commands(pc).data,Commands(PC).addr,Commands(pc).data_nr,Commands(pc).Enable);
                  when "ABRT" => ABRT;
                  when others	 => null;
               end case;
            end loop;
         end if;
     end Main_Case;
  ---------------------------------------------------------------------
  -- MS32PCI_MAIN : process begins
  ---------------------------------------------------------------------
  begin
     Init;
     Main_case;
  end process;
end Behavior; --================= End of architecture ===============--
-----------------------------------------------------------------------
-- Revision list
-- Version     Author          Date           Changes
--
-- 0.1       Ovidiu Lupas   June 09, 2000     New model
-----------------------------------------------------------------------
 
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.