| 1 | // Copyright (C) 2005 Peio Azkarate, peio@opencores.org\r |
| 2 | //\r |
| 3 | // This source file is free software; you can redistribute it\r |
| 4 | // and/or modify it under the terms of the GNU Lesser General\r |
| 5 | // Public License as published by the Free Software Foundation;\r |
| 6 | // either version 2.1 of the License, or (at your option) any\r |
| 7 | // later version.\r |
| 8 | //\r |
| 9 | \r |
| 10 | (* signal_encoding = "user" *)\r |
| 11 | (* safe_implementation = "yes" *)\r |
| 12 | \r |
| 13 | module pciwbsequ_new ( clk_i, nrst_i, cmd_i, cbe_i, frame_i, irdy_i, devsel_o, \r |
| 14 | trdy_o, adrcfg_i, adrmem_i, pciadrLD_o, pcidOE_o, parOE_o, wbdatLD_o, \r |
| 15 | wbrgdMX_o, wbd16MX_o, wrcfg_o, rdcfg_o, wb_sel_o, wb_we_o, wb_stb_o, \r |
| 16 | wb_cyc_o, wb_ack_i, wb_err_i, debug_init, debug_access );\r |
| 17 | \r |
| 18 | // General \r |
| 19 | input clk_i;\r |
| 20 | input nrst_i;\r |
| 21 | // pci \r |
| 22 | // adr_i\r |
| 23 | input [3:0] cmd_i;\r |
| 24 | input [3:0] cbe_i;\r |
| 25 | input frame_i;\r |
| 26 | input irdy_i;\r |
| 27 | output devsel_o;\r |
| 28 | output trdy_o;\r |
| 29 | // control\r |
| 30 | input adrcfg_i;\r |
| 31 | input adrmem_i;\r |
| 32 | output pciadrLD_o;\r |
| 33 | output pcidOE_o;\r |
| 34 | output reg parOE_o;\r |
| 35 | output wbdatLD_o;\r |
| 36 | output wbrgdMX_o;\r |
| 37 | output wbd16MX_o;\r |
| 38 | output wrcfg_o;\r |
| 39 | output rdcfg_o;\r |
| 40 | // whisbone\r |
| 41 | output [1:0] wb_sel_o;\r |
| 42 | output wb_we_o;\r |
| 43 | inout wb_stb_o;\r |
| 44 | output wb_cyc_o;\r |
| 45 | input wb_ack_i;\r |
| 46 | input wb_err_i;\r |
| 47 | // debug signals\r |
| 48 | output reg debug_init;\r |
| 49 | output reg debug_access;\r |
| 50 | \r |
| 51 | //type PciFSM is ( PCIIDLE, B_BUSY, S_DATA1, S_DATA2, TURN_AR ); \r |
| 52 | //wire pst_pci : PciFSM;\r |
| 53 | //wire nxt_pci : PciFSM;\r |
| 54 | \r |
| 55 | // typedef enum reg [2:0] {\r |
| 56 | // RED, GREEN, BLUE, CYAN, MAGENTA, YELLOW\r |
| 57 | // } color_t;\r |
| 58 | //\r |
| 59 | // color_t my_color = GREEN;\r |
| 60 | \r |
| 61 | // parameter PCIIDLE = 2'b00;\r |
| 62 | // parameter B_BUSY = 2'b01;\r |
| 63 | // parameter S_DATA1 = 2'b10;\r |
| 64 | // parameter S_DATA2 = 2'b11;\r |
| 65 | // parameter TURN_AR = 3'b100;\r |
| 66 | \r |
| 67 | reg [2:0] pst_pci;\r |
| 68 | reg [2:0] nxt_pci;\r |
| 69 | \r |
| 70 | parameter [2:0] \r |
| 71 | PCIIDLE = 3'b000,\r |
| 72 | B_BUSY = 3'b001,\r |
| 73 | S_DATA1 = 3'b010,\r |
| 74 | S_DATA2 = 3'b011,\r |
| 75 | TURN_AR = 3'b100;\r |
| 76 | \r |
| 77 | \r |
| 78 | initial begin\r |
| 79 | pst_pci = 3'b000;\r |
| 80 | end\r |
| 81 | \r |
| 82 | initial begin\r |
| 83 | nxt_pci = 3'b000;\r |
| 84 | end\r |
| 85 | \r |
| 86 | wire sdata1;\r |
| 87 | wire sdata2;\r |
| 88 | wire idleNX;\r |
| 89 | wire sdata1NX;\r |
| 90 | wire sdata2NX;\r |
| 91 | wire turnarNX;\r |
| 92 | wire idle;\r |
| 93 | reg devselNX_n;\r |
| 94 | reg trdyNX_n;\r |
| 95 | reg devsel;\r |
| 96 | reg trdy;\r |
| 97 | wire adrpci;\r |
| 98 | wire acking;\r |
| 99 | wire rdcfg;\r |
| 100 | reg targOE;\r |
| 101 | reg pcidOE;\r |
| 102 | \r |
| 103 | // always @(nrst_i or clk_i or nxt_pci)\r |
| 104 | always @(negedge nrst_i or posedge clk_i)\r |
| 105 | begin\r |
| 106 | if( nrst_i == 0 )\r |
| 107 | pst_pci <= PCIIDLE;\r |
| 108 | else \r |
| 109 | pst_pci <= nxt_pci; \r |
| 110 | end\r |
| 111 | \r |
| 112 | // always @(negedge nrst_i or posedge clk_i)\r |
| 113 | always @( pst_pci or frame_i or irdy_i or adrcfg_i or adrpci or acking )\r |
| 114 | begin\r |
| 115 | devselNX_n <= 1'b1;\r |
| 116 | trdyNX_n <= 1'b1; \r |
| 117 | case (pst_pci)\r |
| 118 | PCIIDLE : \r |
| 119 | begin\r |
| 120 | if ( frame_i == 0 )\r |
| 121 | nxt_pci <= B_BUSY; \r |
| 122 | else\r |
| 123 | nxt_pci <= PCIIDLE;\r |
| 124 | end\r |
| 125 | B_BUSY:\r |
| 126 | if ( adrpci == 0 )\r |
| 127 | nxt_pci <= TURN_AR;\r |
| 128 | else\r |
| 129 | begin\r |
| 130 | nxt_pci <= S_DATA1;\r |
| 131 | devselNX_n <= 0; \r |
| 132 | end\r |
| 133 | S_DATA1:\r |
| 134 | if ( acking == 1 )\r |
| 135 | begin\r |
| 136 | nxt_pci <= S_DATA2;\r |
| 137 | devselNX_n <= 0; \r |
| 138 | trdyNX_n <= 0; \r |
| 139 | end\r |
| 140 | else\r |
| 141 | begin\r |
| 142 | nxt_pci <= S_DATA1;\r |
| 143 | devselNX_n <= 0; \r |
| 144 | end\r |
| 145 | S_DATA2:\r |
| 146 | if ( frame_i == 1 && irdy_i == 0 )\r |
| 147 | nxt_pci <= TURN_AR;\r |
| 148 | else\r |
| 149 | begin\r |
| 150 | nxt_pci <= S_DATA2;\r |
| 151 | devselNX_n <= 0;\r |
| 152 | trdyNX_n <= 0;\r |
| 153 | end\r |
| 154 | TURN_AR:\r |
| 155 | if ( frame_i == 1 )\r |
| 156 | nxt_pci <= PCIIDLE;\r |
| 157 | else\r |
| 158 | nxt_pci <= TURN_AR;\r |
| 159 | endcase\r |
| 160 | end\r |
| 161 | \r |
| 162 | // FSM control signals\r |
| 163 | assign adrpci = adrmem_i;\r |
| 164 | \r |
| 165 | assign acking = (\r |
| 166 | ( wb_ack_i == 1 || wb_err_i == 1 ) || \r |
| 167 | ( adrcfg_i == 1 && irdy_i == 0)\r |
| 168 | ) ? 1'b1 : 1'b0; \r |
| 169 | \r |
| 170 | // FSM derived Control signals\r |
| 171 | assign idle = ( pst_pci <= PCIIDLE ) ? 1'b1 : 1'b0;\r |
| 172 | assign sdata1 = ( pst_pci <= S_DATA1 ) ? 1'b1 : 1'b0;\r |
| 173 | assign sdata2 = ( pst_pci <= S_DATA2 ) ? 1'b1 : 1'b0;\r |
| 174 | assign idleNX = ( nxt_pci <= PCIIDLE ) ? 1'b1 : 1'b0;\r |
| 175 | assign sdata1NX = ( nxt_pci <= S_DATA1 ) ? 1'b1 : 1'b0;\r |
| 176 | assign sdata2NX = ( nxt_pci <= S_DATA2 ) ? 1'b1 : 1'b0;\r |
| 177 | assign turnarNX = ( nxt_pci <= TURN_AR ) ? 1'b1 : 1'b0;\r |
| 178 | \r |
| 179 | // PCI Data Output Enable\r |
| 180 | // always @( nrst_i or clk_i or cmd_i [0] or sdata1NX or turnarNX )\r |
| 181 | always @(negedge nrst_i or posedge clk_i)\r |
| 182 | begin\r |
| 183 | if ( nrst_i == 0 )\r |
| 184 | pcidOE <= 0;\r |
| 185 | else\r |
| 186 | if ( sdata1NX == 1 && cmd_i [0] == 0 )\r |
| 187 | pcidOE <= 1;\r |
| 188 | else \r |
| 189 | if ( turnarNX == 1 )\r |
| 190 | pcidOE <= 0;\r |
| 191 | end\r |
| 192 | \r |
| 193 | assign pcidOE_o = pcidOE;\r |
| 194 | \r |
| 195 | // PAR Output Enable\r |
| 196 | // PCI Read data phase\r |
| 197 | // PAR is valid 1 cicle after data is valid\r |
| 198 | // always @( nrst_i or clk_i or cmd_i [0] or sdata2NX or turnarNX )\r |
| 199 | always @(negedge nrst_i or posedge clk_i)\r |
| 200 | begin\r |
| 201 | if ( nrst_i == 0 )\r |
| 202 | parOE_o <= 0;\r |
| 203 | else\r |
| 204 | if ( ( sdata2NX == 1 || turnarNX == 1 ) && cmd_i [0] == 0 )\r |
| 205 | parOE_o <= 1;\r |
| 206 | else\r |
| 207 | parOE_o <= 0;\r |
| 208 | end\r |
| 209 | \r |
| 210 | // Target s/t/s signals OE control\r |
| 211 | // targOE <= '1' when ( idle = '0' and adrpci = '1' ) else '0';\r |
| 212 | // always @( nrst_i or clk_i or sdata1NX or idleNX )\r |
| 213 | always @(negedge nrst_i or posedge clk_i)\r |
| 214 | begin\r |
| 215 | if ( nrst_i == 0 )\r |
| 216 | targOE <= 0;\r |
| 217 | else\r |
| 218 | if ( sdata1NX == 1 )\r |
| 219 | targOE <= 1;\r |
| 220 | else \r |
| 221 | if ( idleNX == 1 )\r |
| 222 | targOE <= 0;\r |
| 223 | end\r |
| 224 | \r |
| 225 | // WHISBONE outs\r |
| 226 | assign wb_cyc_o = (adrmem_i == 1 && sdata1 == 1) ? 1'b1 : 1'b0;\r |
| 227 | assign wb_stb_o = (adrmem_i == 1 && sdata1 == 1 && irdy_i == 0 ) ? 1'b1 : 1'b0;\r |
| 228 | \r |
| 229 | // PCI(Little endian) to WB(Big endian)\r |
| 230 | assign wb_sel_o [1] = (! cbe_i [0]) || (! cbe_i [2]);\r |
| 231 | assign wb_sel_o [0] = (! cbe_i [1]) || (! cbe_i [3]); \r |
| 232 | \r |
| 233 | assign wb_we_o = cmd_i [0];\r |
| 234 | \r |
| 235 | // Syncronized PCI outs\r |
| 236 | always @(negedge nrst_i or posedge clk_i)\r |
| 237 | begin\r |
| 238 | if( nrst_i == 0 )\r |
| 239 | begin\r |
| 240 | devsel <= 1;\r |
| 241 | trdy <= 1;\r |
| 242 | end\r |
| 243 | else\r |
| 244 | begin\r |
| 245 | devsel <= devselNX_n;\r |
| 246 | trdy <= trdyNX_n;\r |
| 247 | end\r |
| 248 | end\r |
| 249 | \r |
| 250 | assign devsel_o = ( targOE == 1 ) ? devsel : 1'bZ;\r |
| 251 | assign trdy_o = ( targOE == 1 ) ? trdy : 1'bZ;\r |
| 252 | \r |
| 253 | // rd/wr Configuration Space Registers\r |
| 254 | assign wrcfg_o = (\r |
| 255 | adrcfg_i == 1 &&\r |
| 256 | cmd_i [0] == 1 &&\r |
| 257 | sdata2 == 1\r |
| 258 | ) ? 1'b1 : 1'b0;\r |
| 259 | \r |
| 260 | assign rdcfg = (\r |
| 261 | adrcfg_i == 1 &&\r |
| 262 | cmd_i [0] == 0 &&\r |
| 263 | (sdata1 == 1 || sdata2 == 1)\r |
| 264 | ) ? 1'b1 : 1'b0;\r |
| 265 | \r |
| 266 | assign rdcfg_o = rdcfg;\r |
| 267 | \r |
| 268 | // LoaD enable signals\r |
| 269 | assign pciadrLD_o = ! frame_i;\r |
| 270 | assign wbdatLD_o = wb_ack_i;\r |
| 271 | \r |
| 272 | // Mux control signals\r |
| 273 | assign wbrgdMX_o = ! rdcfg;\r |
| 274 | assign wbd16MX_o = (cbe_i [3] == 0 || cbe_i [2] == 0) ? 1'b1 : 1'b0;\r |
| 275 | \r |
| 276 | // debug outs \r |
| 277 | always @(negedge nrst_i or posedge clk_i)\r |
| 278 | begin\r |
| 279 | if ( nrst_i == 0 )\r |
| 280 | debug_init <= 0;\r |
| 281 | else\r |
| 282 | if (devsel == 0)\r |
| 283 | debug_init <= 1;\r |
| 284 | end\r |
| 285 | \r |
| 286 | always @(negedge nrst_i or posedge clk_i)\r |
| 287 | begin\r |
| 288 | if ( nrst_i == 0 )\r |
| 289 | debug_access <= 0;\r |
| 290 | else\r |
| 291 | if (wb_stb_o == 1)\r |
| 292 | debug_access <= 1;\r |
| 293 | end\r |
| 294 | \r |
| 295 | endmodule\r |