X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/raggedstone/blobdiff_plain/b983c58b8128671dc7e2c8252af87fbb3aea4134..ebba63a9f3199fec28ffd25951257b6619feb8bf:/dhwk_old/source/pciwbsequ.vhd diff --git a/dhwk_old/source/pciwbsequ.vhd b/dhwk_old/source/pciwbsequ.vhd new file mode 100644 index 0000000..61744cf --- /dev/null +++ b/dhwk_old/source/pciwbsequ.vhd @@ -0,0 +1,382 @@ +--+-------------------------------------------------------------------------------------------------+ +--| | +--| File: pciwbsequ.vhd | +--| | +--| Project: pci32tlite_oc | +--| | +--| Description: FSM controlling PCI to Whisbone sequence. | +--| | +--+-------------------------------------------------------------------------------------------------+ +--| | +--| Revision history : | +--| Date Version Author Description | +--| 2005-05-13 R00A00 PAU First alfa revision (eng) | +--| 2006-01-09 MS added debug signals debug_init, debug_access | | +--| | +--| To do: | +--| | +--+-------------------------------------------------------------------------------------------------+ +--+-----------------------------------------------------------------+ +--| | +--| Copyright (C) 2005 Peio Azkarate, peio@opencores.org | +--| | +--| This source file may be used and distributed without | +--| restriction provided that this copyright statement is not | +--| removed from the file and that any derivative work contains | +--| the original copyright notice and the associated disclaimer. | +--| | +--| This source file is free software; you can redistribute it | +--| and/or modify it under the terms of the GNU Lesser General | +--| Public License as published by the Free Software Foundation; | +--| either version 2.1 of the License, or (at your option) any | +--| later version. | +--| | +--| This source is distributed in the hope that it will be | +--| useful, but WITHOUT ANY WARRANTY; without even the implied | +--| warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR | +--| PURPOSE. See the GNU Lesser General Public License for more | +--| details. | +--| | +--| You should have received a copy of the GNU Lesser General | +--| Public License along with this source; if not, download it | +--| from http://www.opencores.org/lgpl.shtml | +--| | +--+-----------------------------------------------------------------+ + + +--+-----------------------------------------------------------------------------+ +--| LIBRARIES | +--+-----------------------------------------------------------------------------+ + +library ieee; +use ieee.std_logic_1164.all; + + +--+-----------------------------------------------------------------------------+ +--| ENTITY | +--+-----------------------------------------------------------------------------+ + +entity pciwbsequ is +port ( + + -- General + clk_i : in std_logic; + nrst_i : in std_logic; + -- pci + --adr_i + cmd_i : in std_logic_vector(3 downto 0); + cbe_i : in std_logic_vector(3 downto 0); + frame_i : in std_logic; + irdy_i : in std_logic; + devsel_o : out std_logic; + trdy_o : out std_logic; + -- control + adrcfg_i : in std_logic; + adrmem_i : in std_logic; + pciadrLD_o : out std_logic; + pcidOE_o : out std_logic; + parOE_o : out std_logic; + wbdatLD_o : out std_logic; + wbrgdMX_o : out std_logic; + wbd16MX_o : out std_logic; + wrcfg_o : out std_logic; + rdcfg_o : out std_logic; + -- whisbone + wb_sel_o : out std_logic_vector(1 downto 0); + wb_we_o : out std_logic; + wb_stb_o : inout std_logic; + wb_cyc_o : out std_logic; + wb_ack_i : in std_logic; + wb_err_i : in std_logic; + -- debug signals + debug_init : out std_logic; + debug_access : out std_logic +); +end pciwbsequ; + + +architecture rtl of pciwbsequ is + + +--+-----------------------------------------------------------------------------+ +--| COMPONENTS | +--+-----------------------------------------------------------------------------+ +--+-----------------------------------------------------------------------------+ +--| CONSTANTS | +--+-----------------------------------------------------------------------------+ +--+-----------------------------------------------------------------------------+ +--| SIGNALS | +--+-----------------------------------------------------------------------------+ + + type PciFSM is ( PCIIDLE, B_BUSY, S_DATA1, S_DATA2, TURN_AR ); + signal pst_pci : PciFSM; + signal nxt_pci : PciFSM; + + signal sdata1 : std_logic; + signal sdata2 : std_logic; + signal idleNX : std_logic; + signal sdata1NX : std_logic; + signal sdata2NX : std_logic; + signal turnarNX : std_logic; + signal idle : std_logic; + signal devselNX_n : std_logic; + signal trdyNX_n : std_logic; + signal devsel : std_logic; + signal trdy : std_logic; + signal adrpci : std_logic; + signal acking : std_logic; + signal rdcfg : std_logic; + signal targOE : std_logic; + signal pcidOE : std_logic; + + +begin + + --+-------------------------------------------------------------------------+ + --| PCI-Whisbone Sequencer | + --+-------------------------------------------------------------------------+ + + + --+-------------------------------------------------------------+ + --| FSM PCI-Whisbone | + --+-------------------------------------------------------------+ + + PCIFSM_CLOCKED: process( nrst_i, clk_i, nxt_pci ) + begin + + if( nrst_i = '0' ) then + pst_pci <= PCIIDLE; + elsif( rising_edge(clk_i) ) then + pst_pci <= nxt_pci; + end if; + + end process PCIFSM_CLOCKED; + + + PCIFSM_COMB: process( pst_pci, frame_i, irdy_i, adrcfg_i, adrpci, acking ) + begin + + devselNX_n <= '1'; + trdyNX_n <= '1'; + case pst_pci is + + when PCIIDLE => + if ( frame_i = '0' ) then + nxt_pci <= B_BUSY; + else + nxt_pci <= PCIIDLE; + end if; + + when B_BUSY => + if ( adrpci = '0' ) then + nxt_pci <= TURN_AR; + else + nxt_pci <= S_DATA1; + devselNX_n <= '0'; + end if; + + when S_DATA1 => + if ( acking = '1' ) then + nxt_pci <= S_DATA2; + devselNX_n <= '0'; + trdyNX_n <= '0'; + else + nxt_pci <= S_DATA1; + devselNX_n <= '0'; + end if; + + when S_DATA2 => + if ( frame_i = '1' and irdy_i = '0' ) then + nxt_pci <= TURN_AR; + else + nxt_pci <= S_DATA2; + devselNX_n <= '0'; + trdyNX_n <= '0'; + end if; + + when TURN_AR => + if ( frame_i = '1' ) then + nxt_pci <= PCIIDLE; + else + nxt_pci <= TURN_AR; + end if; + + end case; + + end process PCIFSM_COMB; + + + --+-------------------------------------------------------------+ + --| FSM control signals | + --+-------------------------------------------------------------+ + + adrpci <= adrmem_i or adrcfg_i; + acking <= '1' when ( wb_ack_i = '1' or wb_err_i = '1' ) or ( adrcfg_i = '1' and irdy_i = '0') + else '0'; + + + --+-------------------------------------------------------------+ + --| FSM derived Control signals | + --+-------------------------------------------------------------+ + idle <= '1' when ( pst_pci = PCIIDLE ) else '0'; + sdata1 <= '1' when ( pst_pci = S_DATA1 ) else '0'; + sdata2 <= '1' when ( pst_pci = S_DATA2 ) else '0'; + idleNX <= '1' when ( nxt_pci = PCIIDLE ) else '0'; + sdata1NX <= '1' when ( nxt_pci = S_DATA1 ) else '0'; + sdata2NX <= '1' when ( nxt_pci = S_DATA2 ) else '0'; + turnarNX <= '1' when ( nxt_pci = TURN_AR ) else '0'; + + + + --+-------------------------------------------------------------+ + --| PCI Data Output Enable | + --+-------------------------------------------------------------+ + + PCIDOE_P: process( nrst_i, clk_i, cmd_i(0), sdata1NX, turnarNX ) + begin + + if ( nrst_i = '0' ) then + pcidOE <= '0'; + elsif ( rising_edge(clk_i) ) then + + if ( sdata1NX = '1' and cmd_i(0) = '0' ) then + pcidOE <= '1'; + elsif ( turnarNX = '1' ) then + pcidOE <= '0'; + end if; + + end if; + + end process PCIDOE_P; + + pcidOE_o <= pcidOE; + + + --+-------------------------------------------------------------+ + --| PAR Output Enable | + --| PCI Read data phase | + --| PAR is valid 1 cicle after data is valid | + --+-------------------------------------------------------------+ + + PAROE_P: process( nrst_i, clk_i, cmd_i(0), sdata2NX, turnarNX ) + begin + + if ( nrst_i = '0' ) then + parOE_o <= '0'; + elsif ( rising_edge(clk_i) ) then + + if ( ( sdata2NX = '1' or turnarNX = '1' ) and cmd_i(0) = '0' ) then + parOE_o <= '1'; + else + parOE_o <= '0'; + end if; + + end if; + + end process PAROE_P; + + + --+-------------------------------------------------------------+ + --| Target s/t/s signals OE control | + --+-------------------------------------------------------------+ + +-- targOE <= '1' when ( idle = '0' and adrpci = '1' ) else '0'; + TARGOE_P: process( nrst_i, clk_i, sdata1NX, idleNX ) + begin + + if ( nrst_i = '0' ) then + targOE <= '0'; + elsif ( rising_edge(clk_i) ) then + + if ( sdata1NX = '1' ) then + targOE <= '1'; + elsif ( idleNX = '1' ) then + targOE <= '0'; + end if; + + end if; + + end process TARGOE_P; + + + --+-------------------------------------------------------------------------+ + --| WHISBONE outs | + --+-------------------------------------------------------------------------+ + + wb_cyc_o <= '1' when ( adrmem_i = '1' and sdata1 = '1' ) else '0'; + wb_stb_o <= '1' when ( adrmem_i = '1' and sdata1 = '1' and irdy_i = '0' ) else '0'; + + -- PCI(Little endian) to WB(Big endian) + wb_sel_o(1) <= (not cbe_i(0)) or (not cbe_i(2)); + wb_sel_o(0) <= (not cbe_i(1)) or (not cbe_i(3)); + -- + wb_we_o <= cmd_i(0); + + + --+-------------------------------------------------------------------------+ + --| Syncronized PCI outs | + --+-------------------------------------------------------------------------+ + + PCISIG: process( nrst_i, clk_i, devselNX_n, trdyNX_n) + begin + + if( nrst_i = '0' ) then + devsel <= '1'; + trdy <= '1'; + elsif( rising_edge(clk_i) ) then + + devsel <= devselNX_n; + trdy <= trdyNX_n; + + end if; + + end process PCISIG; + + devsel_o <= devsel when ( targOE = '1' ) else 'Z'; + trdy_o <= trdy when ( targOE = '1' ) else 'Z'; + + + --+-------------------------------------------------------------------------+ + --| Other outs | + --+-------------------------------------------------------------------------+ + + -- rd/wr Configuration Space Registers + wrcfg_o <= '1' when ( adrcfg_i = '1' and cmd_i(0) = '1' and sdata2 = '1' ) else '0'; + rdcfg <= '1' when ( adrcfg_i = '1' and cmd_i(0) = '0' and ( sdata1 = '1' or sdata2 = '1' ) ) else '0'; + rdcfg_o <= rdcfg; + + -- LoaD enable signals + pciadrLD_o <= not frame_i; + wbdatLD_o <= wb_ack_i; + + -- Mux control signals + wbrgdMX_o <= not rdcfg; + wbd16MX_o <= '1' when ( cbe_i(3) = '0' or cbe_i(2) = '0' ) else '0'; + + --+-------------------------------------------------------------------------+ + --| debug outs | + --+-------------------------------------------------------------------------+ + + process (nrst_i, clk_i) + begin + if ( nrst_i = '0' ) then + debug_init <= '0'; + elsif clk_i'event and clk_i = '1' then + if devsel = '0' then + debug_init <= '1'; + end if; + end if; + end process; + + process (nrst_i, clk_i) + begin + if ( nrst_i = '0' ) then + debug_access <= '0'; + elsif clk_i'event and clk_i = '1' then + if wb_stb_o = '1' then + debug_access <= '1'; + end if; + end if; + end process; + +end rtl;