| 1 | --+-------------------------------------------------------------------------------------------------+\r |
| 2 | --| |\r |
| 3 | --| File: pciwbsequ.vhd |\r |
| 4 | --| |\r |
| 5 | --| Project: pci32tlite_oc |\r |
| 6 | --| |\r |
| 7 | --| Description: FSM controlling PCI to Whisbone sequence. |\r |
| 8 | --| |\r |
| 9 | --+-------------------------------------------------------------------------------------------------+\r |
| 10 | --| |\r |
| 11 | --| Revision history : |\r |
| 12 | --| Date Version Author Description |\r |
| 13 | --| 2005-05-13 R00A00 PAU First alfa revision (eng) |\r |
| 14 | --| 2006-01-09 MS added debug signals debug_init, debug_access | |\r |
| 15 | --| |\r |
| 16 | --| To do: |\r |
| 17 | --| |\r |
| 18 | --+-------------------------------------------------------------------------------------------------+\r |
| 19 | --+-----------------------------------------------------------------+\r |
| 20 | --| |\r |
| 21 | --| Copyright (C) 2005 Peio Azkarate, peio@opencores.org | \r |
| 22 | --| |\r |
| 23 | --| This source file may be used and distributed without |\r |
| 24 | --| restriction provided that this copyright statement is not |\r |
| 25 | --| removed from the file and that any derivative work contains |\r |
| 26 | --| the original copyright notice and the associated disclaimer. |\r |
| 27 | --| |\r |
| 28 | --| This source file is free software; you can redistribute it |\r |
| 29 | --| and/or modify it under the terms of the GNU Lesser General |\r |
| 30 | --| Public License as published by the Free Software Foundation; |\r |
| 31 | --| either version 2.1 of the License, or (at your option) any |\r |
| 32 | --| later version. |\r |
| 33 | --| |\r |
| 34 | --| This source is distributed in the hope that it will be |\r |
| 35 | --| useful, but WITHOUT ANY WARRANTY; without even the implied |\r |
| 36 | --| warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |\r |
| 37 | --| PURPOSE. See the GNU Lesser General Public License for more |\r |
| 38 | --| details. |\r |
| 39 | --| |\r |
| 40 | --| You should have received a copy of the GNU Lesser General |\r |
| 41 | --| Public License along with this source; if not, download it |\r |
| 42 | --| from http://www.opencores.org/lgpl.shtml |\r |
| 43 | --| |\r |
| 44 | --+-----------------------------------------------------------------+ \r |
| 45 | \r |
| 46 | \r |
| 47 | --+-----------------------------------------------------------------------------+\r |
| 48 | --| LIBRARIES |\r |
| 49 | --+-----------------------------------------------------------------------------+\r |
| 50 | \r |
| 51 | library ieee;\r |
| 52 | use ieee.std_logic_1164.all;\r |
| 53 | \r |
| 54 | \r |
| 55 | --+-----------------------------------------------------------------------------+\r |
| 56 | --| ENTITY |\r |
| 57 | --+-----------------------------------------------------------------------------+\r |
| 58 | \r |
| 59 | entity pciwbsequ is\r |
| 60 | port (\r |
| 61 | \r |
| 62 | -- General \r |
| 63 | clk_i : in std_logic;\r |
| 64 | nrst_i : in std_logic;\r |
| 65 | -- pci \r |
| 66 | --adr_i\r |
| 67 | cmd_i : in std_logic_vector(3 downto 0);\r |
| 68 | cbe_i : in std_logic_vector(3 downto 0);\r |
| 69 | frame_i : in std_logic;\r |
| 70 | irdy_i : in std_logic;\r |
| 71 | devsel_o : out std_logic;\r |
| 72 | trdy_o : out std_logic;\r |
| 73 | -- control\r |
| 74 | adrcfg_i : in std_logic;\r |
| 75 | adrmem_i : in std_logic;\r |
| 76 | pciadrLD_o : out std_logic;\r |
| 77 | pcidOE_o : out std_logic;\r |
| 78 | parOE_o : out std_logic;\r |
| 79 | wbdatLD_o : out std_logic;\r |
| 80 | wbrgdMX_o : out std_logic;\r |
| 81 | wbd16MX_o : out std_logic; \r |
| 82 | wrcfg_o : out std_logic;\r |
| 83 | rdcfg_o : out std_logic;\r |
| 84 | -- whisbone\r |
| 85 | wb_sel_o : out std_logic_vector(1 downto 0);\r |
| 86 | wb_we_o : out std_logic;\r |
| 87 | wb_stb_o : inout std_logic; \r |
| 88 | wb_cyc_o : out std_logic;\r |
| 89 | wb_ack_i : in std_logic;\r |
| 90 | wb_err_i : in std_logic; \r |
| 91 | -- debug signals\r |
| 92 | debug_init : out std_logic;\r |
| 93 | debug_access : out std_logic \r |
| 94 | ); \r |
| 95 | end pciwbsequ;\r |
| 96 | \r |
| 97 | \r |
| 98 | architecture rtl of pciwbsequ is\r |
| 99 | \r |
| 100 | \r |
| 101 | --+-----------------------------------------------------------------------------+\r |
| 102 | --| COMPONENTS |\r |
| 103 | --+-----------------------------------------------------------------------------+\r |
| 104 | --+-----------------------------------------------------------------------------+\r |
| 105 | --| CONSTANTS |\r |
| 106 | --+-----------------------------------------------------------------------------+\r |
| 107 | --+-----------------------------------------------------------------------------+\r |
| 108 | --| SIGNALS |\r |
| 109 | --+-----------------------------------------------------------------------------+\r |
| 110 | \r |
| 111 | type PciFSM is ( PCIIDLE, B_BUSY, S_DATA1, S_DATA2, TURN_AR ); \r |
| 112 | signal pst_pci : PciFSM;\r |
| 113 | signal nxt_pci : PciFSM;\r |
| 114 | \r |
| 115 | signal sdata1 : std_logic;\r |
| 116 | signal sdata2 : std_logic;\r |
| 117 | signal idleNX : std_logic;\r |
| 118 | signal sdata1NX : std_logic;\r |
| 119 | signal sdata2NX : std_logic;\r |
| 120 | signal turnarNX : std_logic;\r |
| 121 | signal idle : std_logic;\r |
| 122 | signal devselNX_n : std_logic;\r |
| 123 | signal trdyNX_n : std_logic;\r |
| 124 | signal devsel : std_logic;\r |
| 125 | signal trdy : std_logic;\r |
| 126 | signal adrpci : std_logic;\r |
| 127 | signal acking : std_logic;\r |
| 128 | signal rdcfg : std_logic;\r |
| 129 | signal targOE : std_logic;\r |
| 130 | signal pcidOE : std_logic;\r |
| 131 | \r |
| 132 | \r |
| 133 | begin\r |
| 134 | \r |
| 135 | --+-------------------------------------------------------------------------+\r |
| 136 | --| PCI-Whisbone Sequencer |\r |
| 137 | --+-------------------------------------------------------------------------+\r |
| 138 | \r |
| 139 | \r |
| 140 | --+-------------------------------------------------------------+\r |
| 141 | --| FSM PCI-Whisbone |\r |
| 142 | --+-------------------------------------------------------------+\r |
| 143 | \r |
| 144 | PCIFSM_CLOCKED: process( nrst_i, clk_i, nxt_pci )\r |
| 145 | begin\r |
| 146 | \r |
| 147 | if( nrst_i = '0' ) then\r |
| 148 | pst_pci <= PCIIDLE;\r |
| 149 | elsif( rising_edge(clk_i) ) then\r |
| 150 | pst_pci <= nxt_pci; \r |
| 151 | end if;\r |
| 152 | \r |
| 153 | end process PCIFSM_CLOCKED;\r |
| 154 | \r |
| 155 | \r |
| 156 | PCIFSM_COMB: process( pst_pci, frame_i, irdy_i, adrcfg_i, adrpci, acking )\r |
| 157 | begin\r |
| 158 | \r |
| 159 | devselNX_n <= '1';\r |
| 160 | trdyNX_n <= '1'; \r |
| 161 | case pst_pci is\r |
| 162 | \r |
| 163 | when PCIIDLE =>\r |
| 164 | if ( frame_i = '0' ) then \r |
| 165 | nxt_pci <= B_BUSY; \r |
| 166 | else\r |
| 167 | nxt_pci <= PCIIDLE;\r |
| 168 | end if; \r |
| 169 | \r |
| 170 | when B_BUSY =>\r |
| 171 | if ( adrpci = '0' ) then\r |
| 172 | nxt_pci <= TURN_AR;\r |
| 173 | else\r |
| 174 | nxt_pci <= S_DATA1;\r |
| 175 | devselNX_n <= '0'; \r |
| 176 | end if;\r |
| 177 | \r |
| 178 | when S_DATA1 =>\r |
| 179 | if ( acking = '1' ) then \r |
| 180 | nxt_pci <= S_DATA2;\r |
| 181 | devselNX_n <= '0'; \r |
| 182 | trdyNX_n <= '0'; \r |
| 183 | else\r |
| 184 | nxt_pci <= S_DATA1;\r |
| 185 | devselNX_n <= '0'; \r |
| 186 | end if; \r |
| 187 | \r |
| 188 | when S_DATA2 => \r |
| 189 | if ( frame_i = '1' and irdy_i = '0' ) then \r |
| 190 | nxt_pci <= TURN_AR;\r |
| 191 | else\r |
| 192 | nxt_pci <= S_DATA2;\r |
| 193 | devselNX_n <= '0'; \r |
| 194 | trdyNX_n <= '0'; \r |
| 195 | end if; \r |
| 196 | \r |
| 197 | when TURN_AR =>\r |
| 198 | if ( frame_i = '1' ) then\r |
| 199 | nxt_pci <= PCIIDLE;\r |
| 200 | else\r |
| 201 | nxt_pci <= TURN_AR;\r |
| 202 | end if;\r |
| 203 | \r |
| 204 | end case;\r |
| 205 | \r |
| 206 | end process PCIFSM_COMB; \r |
| 207 | \r |
| 208 | \r |
| 209 | --+-------------------------------------------------------------+\r |
| 210 | --| FSM control signals |\r |
| 211 | --+-------------------------------------------------------------+\r |
| 212 | \r |
| 213 | adrpci <= adrmem_i or adrcfg_i;\r |
| 214 | acking <= '1' when ( wb_ack_i = '1' or wb_err_i = '1' ) or ( adrcfg_i = '1' and irdy_i = '0')\r |
| 215 | else '0'; \r |
| 216 | \r |
| 217 | \r |
| 218 | --+-------------------------------------------------------------+\r |
| 219 | --| FSM derived Control signals |\r |
| 220 | --+-------------------------------------------------------------+\r |
| 221 | idle <= '1' when ( pst_pci = PCIIDLE ) else '0';\r |
| 222 | sdata1 <= '1' when ( pst_pci = S_DATA1 ) else '0';\r |
| 223 | sdata2 <= '1' when ( pst_pci = S_DATA2 ) else '0';\r |
| 224 | idleNX <= '1' when ( nxt_pci = PCIIDLE ) else '0';\r |
| 225 | sdata1NX <= '1' when ( nxt_pci = S_DATA1 ) else '0'; \r |
| 226 | sdata2NX <= '1' when ( nxt_pci = S_DATA2 ) else '0';\r |
| 227 | turnarNX <= '1' when ( nxt_pci = TURN_AR ) else '0';\r |
| 228 | \r |
| 229 | \r |
| 230 | \r |
| 231 | --+-------------------------------------------------------------+\r |
| 232 | --| PCI Data Output Enable |\r |
| 233 | --+-------------------------------------------------------------+\r |
| 234 | \r |
| 235 | PCIDOE_P: process( nrst_i, clk_i, cmd_i(0), sdata1NX, turnarNX )\r |
| 236 | begin\r |
| 237 | \r |
| 238 | if ( nrst_i = '0' ) then \r |
| 239 | pcidOE <= '0';\r |
| 240 | elsif ( rising_edge(clk_i) ) then \r |
| 241 | \r |
| 242 | if ( sdata1NX = '1' and cmd_i(0) = '0' ) then\r |
| 243 | pcidOE <= '1';\r |
| 244 | elsif ( turnarNX = '1' ) then\r |
| 245 | pcidOE <= '0';\r |
| 246 | end if; \r |
| 247 | \r |
| 248 | end if;\r |
| 249 | \r |
| 250 | end process PCIDOE_P;\r |
| 251 | \r |
| 252 | pcidOE_o <= pcidOE;\r |
| 253 | \r |
| 254 | \r |
| 255 | --+-------------------------------------------------------------+\r |
| 256 | --| PAR Output Enable |\r |
| 257 | --| PCI Read data phase |\r |
| 258 | --| PAR is valid 1 cicle after data is valid |\r |
| 259 | --+-------------------------------------------------------------+\r |
| 260 | \r |
| 261 | PAROE_P: process( nrst_i, clk_i, cmd_i(0), sdata2NX, turnarNX )\r |
| 262 | begin\r |
| 263 | \r |
| 264 | if ( nrst_i = '0' ) then \r |
| 265 | parOE_o <= '0';\r |
| 266 | elsif ( rising_edge(clk_i) ) then \r |
| 267 | \r |
| 268 | if ( ( sdata2NX = '1' or turnarNX = '1' ) and cmd_i(0) = '0' ) then\r |
| 269 | parOE_o <= '1';\r |
| 270 | else\r |
| 271 | parOE_o <= '0';\r |
| 272 | end if; \r |
| 273 | \r |
| 274 | end if;\r |
| 275 | \r |
| 276 | end process PAROE_P;\r |
| 277 | \r |
| 278 | \r |
| 279 | --+-------------------------------------------------------------+\r |
| 280 | --| Target s/t/s signals OE control |\r |
| 281 | --+-------------------------------------------------------------+\r |
| 282 | \r |
| 283 | -- targOE <= '1' when ( idle = '0' and adrpci = '1' ) else '0';\r |
| 284 | TARGOE_P: process( nrst_i, clk_i, sdata1NX, idleNX )\r |
| 285 | begin\r |
| 286 | \r |
| 287 | if ( nrst_i = '0' ) then \r |
| 288 | targOE <= '0';\r |
| 289 | elsif ( rising_edge(clk_i) ) then \r |
| 290 | \r |
| 291 | if ( sdata1NX = '1' ) then\r |
| 292 | targOE <= '1';\r |
| 293 | elsif ( idleNX = '1' ) then\r |
| 294 | targOE <= '0';\r |
| 295 | end if; \r |
| 296 | \r |
| 297 | end if;\r |
| 298 | \r |
| 299 | end process TARGOE_P;\r |
| 300 | \r |
| 301 | \r |
| 302 | --+-------------------------------------------------------------------------+\r |
| 303 | --| WHISBONE outs |\r |
| 304 | --+-------------------------------------------------------------------------+\r |
| 305 | \r |
| 306 | wb_cyc_o <= '1' when ( adrmem_i = '1' and sdata1 = '1' ) else '0';\r |
| 307 | wb_stb_o <= '1' when ( adrmem_i = '1' and sdata1 = '1' and irdy_i = '0' ) else '0';\r |
| 308 | \r |
| 309 | -- PCI(Little endian) to WB(Big endian)\r |
| 310 | wb_sel_o(1) <= (not cbe_i(0)) or (not cbe_i(2));\r |
| 311 | wb_sel_o(0) <= (not cbe_i(1)) or (not cbe_i(3)); \r |
| 312 | -- \r |
| 313 | wb_we_o <= cmd_i(0);\r |
| 314 | \r |
| 315 | \r |
| 316 | --+-------------------------------------------------------------------------+\r |
| 317 | --| Syncronized PCI outs |\r |
| 318 | --+-------------------------------------------------------------------------+\r |
| 319 | \r |
| 320 | PCISIG: process( nrst_i, clk_i, devselNX_n, trdyNX_n)\r |
| 321 | begin\r |
| 322 | \r |
| 323 | if( nrst_i = '0' ) then \r |
| 324 | devsel <= '1';\r |
| 325 | trdy <= '1';\r |
| 326 | elsif( rising_edge(clk_i) ) then \r |
| 327 | \r |
| 328 | devsel <= devselNX_n;\r |
| 329 | trdy <= trdyNX_n;\r |
| 330 | \r |
| 331 | end if;\r |
| 332 | \r |
| 333 | end process PCISIG;\r |
| 334 | \r |
| 335 | devsel_o <= devsel when ( targOE = '1' ) else 'Z';\r |
| 336 | trdy_o <= trdy when ( targOE = '1' ) else 'Z';\r |
| 337 | \r |
| 338 | \r |
| 339 | --+-------------------------------------------------------------------------+\r |
| 340 | --| Other outs |\r |
| 341 | --+-------------------------------------------------------------------------+\r |
| 342 | \r |
| 343 | -- rd/wr Configuration Space Registers\r |
| 344 | wrcfg_o <= '1' when ( adrcfg_i = '1' and cmd_i(0) = '1' and sdata2 = '1' ) else '0';\r |
| 345 | rdcfg <= '1' when ( adrcfg_i = '1' and cmd_i(0) = '0' and ( sdata1 = '1' or sdata2 = '1' ) ) else '0';\r |
| 346 | rdcfg_o <= rdcfg;\r |
| 347 | \r |
| 348 | -- LoaD enable signals\r |
| 349 | pciadrLD_o <= not frame_i;\r |
| 350 | wbdatLD_o <= wb_ack_i;\r |
| 351 | \r |
| 352 | -- Mux control signals\r |
| 353 | wbrgdMX_o <= not rdcfg;\r |
| 354 | wbd16MX_o <= '1' when ( cbe_i(3) = '0' or cbe_i(2) = '0' ) else '0';\r |
| 355 | \r |
| 356 | --+-------------------------------------------------------------------------+\r |
| 357 | --| debug outs |\r |
| 358 | --+-------------------------------------------------------------------------+\r |
| 359 | \r |
| 360 | process (nrst_i, clk_i)\r |
| 361 | begin\r |
| 362 | if ( nrst_i = '0' ) then\r |
| 363 | debug_init <= '0';\r |
| 364 | elsif clk_i'event and clk_i = '1' then\r |
| 365 | if devsel = '0' then\r |
| 366 | debug_init <= '1';\r |
| 367 | end if;\r |
| 368 | end if;\r |
| 369 | end process; \r |
| 370 | \r |
| 371 | process (nrst_i, clk_i)\r |
| 372 | begin\r |
| 373 | if ( nrst_i = '0' ) then\r |
| 374 | debug_access <= '0';\r |
| 375 | elsif clk_i'event and clk_i = '1' then\r |
| 376 | if wb_stb_o = '1' then\r |
| 377 | debug_access <= '1';\r |
| 378 | end if;\r |
| 379 | end if;\r |
| 380 | end process; \r |
| 381 | \r |
| 382 | end rtl;\r |