📄 ms32pci.vhd
字号:
--===================================================================------ 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 + -