| 1 | ////////////////////////////////////////////////////////////////////// |
| 2 | //// //// |
| 3 | //// File name "pci_master32_sm.v" //// |
| 4 | //// //// |
| 5 | //// This file is part of the "PCI bridge" project //// |
| 6 | //// http://www.opencores.org/cores/pci/ //// |
| 7 | //// //// |
| 8 | //// Author(s): //// |
| 9 | //// - Miha Dolenc (mihad@opencores.org) //// |
| 10 | //// //// |
| 11 | //// All additional information is avaliable in the README //// |
| 12 | //// file. //// |
| 13 | //// //// |
| 14 | //// //// |
| 15 | ////////////////////////////////////////////////////////////////////// |
| 16 | //// //// |
| 17 | //// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// |
| 18 | //// //// |
| 19 | //// This source file may be used and distributed without //// |
| 20 | //// restriction provided that this copyright statement is not //// |
| 21 | //// removed from the file and that any derivative work contains //// |
| 22 | //// the original copyright notice and the associated disclaimer. //// |
| 23 | //// //// |
| 24 | //// This source file is free software; you can redistribute it //// |
| 25 | //// and/or modify it under the terms of the GNU Lesser General //// |
| 26 | //// Public License as published by the Free Software Foundation; //// |
| 27 | //// either version 2.1 of the License, or (at your option) any //// |
| 28 | //// later version. //// |
| 29 | //// //// |
| 30 | //// This source is distributed in the hope that it will be //// |
| 31 | //// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
| 32 | //// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
| 33 | //// PURPOSE. See the GNU Lesser General Public License for more //// |
| 34 | //// details. //// |
| 35 | //// //// |
| 36 | //// You should have received a copy of the GNU Lesser General //// |
| 37 | //// Public License along with this source; if not, download it //// |
| 38 | //// from http://www.opencores.org/lgpl.shtml //// |
| 39 | //// //// |
| 40 | ////////////////////////////////////////////////////////////////////// |
| 41 | // |
| 42 | // CVS Revision History |
| 43 | // |
| 44 | // $Log: pci_master32_sm.v,v $ |
| 45 | // Revision 1.1 2007-03-20 17:50:56 sithglan |
| 46 | // add shit |
| 47 | // |
| 48 | // Revision 1.5 2003/01/27 16:49:31 mihad |
| 49 | // Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. |
| 50 | // |
| 51 | // Revision 1.4 2003/01/21 16:06:56 mihad |
| 52 | // Bug fixes, testcases added. |
| 53 | // |
| 54 | // Revision 1.3 2002/02/01 15:25:12 mihad |
| 55 | // Repaired a few bugs, updated specification, added test bench files and design document |
| 56 | // |
| 57 | // Revision 1.2 2001/10/05 08:14:29 mihad |
| 58 | // Updated all files with inclusion of timescale file for simulation purposes. |
| 59 | // |
| 60 | // Revision 1.1.1.1 2001/10/02 15:33:46 mihad |
| 61 | // New project directory structure |
| 62 | // |
| 63 | // |
| 64 | |
| 65 | // module includes pci master state machine and surrounding logic |
| 66 | |
| 67 | // synopsys translate_off |
| 68 | `include "timescale.v" |
| 69 | // synopsys translate_on |
| 70 | `include "pci_constants.v" |
| 71 | |
| 72 | module pci_master32_sm |
| 73 | ( |
| 74 | // system inputs |
| 75 | clk_in, |
| 76 | reset_in, |
| 77 | // arbitration |
| 78 | pci_req_out, |
| 79 | pci_gnt_in, |
| 80 | // master in/outs |
| 81 | pci_frame_in, |
| 82 | pci_frame_out, |
| 83 | pci_frame_out_in, |
| 84 | pci_frame_load_out, |
| 85 | pci_frame_en_in, |
| 86 | pci_frame_en_out, |
| 87 | pci_irdy_in, |
| 88 | pci_irdy_out, |
| 89 | pci_irdy_en_out, |
| 90 | |
| 91 | // target response inputs |
| 92 | pci_trdy_in, |
| 93 | pci_trdy_reg_in, |
| 94 | pci_stop_in, |
| 95 | pci_stop_reg_in, |
| 96 | pci_devsel_in, |
| 97 | pci_devsel_reg_in, |
| 98 | |
| 99 | // address, data, bus command, byte enable in/outs |
| 100 | pci_ad_reg_in, |
| 101 | pci_ad_out, |
| 102 | pci_ad_en_out, |
| 103 | pci_cbe_out, |
| 104 | pci_cbe_en_out, |
| 105 | |
| 106 | // other side of state machine |
| 107 | address_in, |
| 108 | bc_in, |
| 109 | data_in, |
| 110 | data_out, |
| 111 | be_in, |
| 112 | req_in, |
| 113 | rdy_in, |
| 114 | last_in, |
| 115 | next_data_in, |
| 116 | next_be_in, |
| 117 | next_last_in, |
| 118 | ad_load_out, |
| 119 | ad_load_on_transfer_out, |
| 120 | wait_out, |
| 121 | wtransfer_out, |
| 122 | rtransfer_out, |
| 123 | retry_out, |
| 124 | rerror_out, |
| 125 | first_out, |
| 126 | mabort_out, |
| 127 | latency_tim_val_in |
| 128 | ) ; |
| 129 | |
| 130 | // system inputs |
| 131 | input clk_in, |
| 132 | reset_in ; |
| 133 | |
| 134 | /*================================================================================================================== |
| 135 | PCI interface signals - bidirectional signals are divided to inputs and outputs in I/O cells instantiation |
| 136 | module. Enables are separate signals. |
| 137 | ==================================================================================================================*/ |
| 138 | // arbitration |
| 139 | output pci_req_out ; |
| 140 | |
| 141 | input pci_gnt_in ; |
| 142 | |
| 143 | // master in/outs |
| 144 | input pci_frame_in ; |
| 145 | input pci_frame_en_in ; |
| 146 | input pci_frame_out_in ; |
| 147 | |
| 148 | output pci_frame_out, |
| 149 | pci_frame_en_out ; |
| 150 | |
| 151 | output pci_frame_load_out ; |
| 152 | |
| 153 | input pci_irdy_in ; |
| 154 | output pci_irdy_out, |
| 155 | pci_irdy_en_out; |
| 156 | |
| 157 | // target response inputs |
| 158 | input pci_trdy_in, |
| 159 | pci_trdy_reg_in, |
| 160 | pci_stop_in, |
| 161 | pci_stop_reg_in, |
| 162 | pci_devsel_in, |
| 163 | pci_devsel_reg_in ; |
| 164 | |
| 165 | // address, data, bus command, byte enable in/outs |
| 166 | input [31:0] pci_ad_reg_in ; |
| 167 | output [31:0] pci_ad_out ; |
| 168 | |
| 169 | reg [31:0] pci_ad_out ; |
| 170 | |
| 171 | output pci_ad_en_out ; |
| 172 | |
| 173 | output [3:0] pci_cbe_out ; |
| 174 | |
| 175 | reg [3:0] pci_cbe_out ; |
| 176 | |
| 177 | output pci_cbe_en_out ; |
| 178 | |
| 179 | input [31:0] address_in ; // current request address input |
| 180 | |
| 181 | input [3:0] bc_in ; // current request bus command input |
| 182 | |
| 183 | input [31:0] data_in ; // current dataphase data input |
| 184 | |
| 185 | output [31:0] data_out ; // for read operations - current request data output |
| 186 | |
| 187 | reg [31:0] data_out ; |
| 188 | |
| 189 | input [3:0] be_in ; // current dataphase byte enable inputs |
| 190 | |
| 191 | input req_in ; // initiator cycle is requested |
| 192 | input rdy_in ; // requestor indicates that data is ready to be sent for write transaction and ready to |
| 193 | // be received on read transaction |
| 194 | input last_in ; // last dataphase in current transaction indicator |
| 195 | |
| 196 | // status outputs |
| 197 | output wait_out, // wait indicates to the backend that dataphases are not in progress on PCI bus |
| 198 | wtransfer_out, // on any rising clock edge that this status is 1, data is transferred - heavy constraints here |
| 199 | rtransfer_out, // registered transfer indicator - when 1 indicates that data was transfered on previous clock cycle |
| 200 | retry_out, // retry status output - when target signals a retry |
| 201 | rerror_out, // registered error output - when 1 indicates that error was signalled by a target on previous clock cycle |
| 202 | first_out , // indicates whether or not any data was transfered in current transaction |
| 203 | mabort_out; // master abort indicator |
| 204 | |
| 205 | reg wait_out ; |
| 206 | |
| 207 | // latency timer value input - state machine starts latency timer whenever it starts a transaction and last is not |
| 208 | // asserted ( meaning burst transfer ). |
| 209 | input [7:0] latency_tim_val_in ; |
| 210 | |
| 211 | // next data, byte enable and last inputs |
| 212 | input [31:0] next_data_in ; |
| 213 | input [3:0] next_be_in ; |
| 214 | input next_last_in ; |
| 215 | |
| 216 | // clock enable for data output flip-flops - whenever data is transfered, sm loads next data to those flip flops |
| 217 | output ad_load_out, |
| 218 | ad_load_on_transfer_out ; |
| 219 | |
| 220 | // parameters - states - one hot |
| 221 | // idle state |
| 222 | parameter S_IDLE = 4'h1 ; |
| 223 | |
| 224 | // address state |
| 225 | parameter S_ADDRESS = 4'h2 ; |
| 226 | |
| 227 | // transfer state - dataphases |
| 228 | parameter S_TRANSFER = 4'h4 ; |
| 229 | |
| 230 | // turn arround state |
| 231 | parameter S_TA_END = 4'h8 ; |
| 232 | |
| 233 | // change state - clock enable for sm state register |
| 234 | wire change_state ; |
| 235 | // next state for state machine |
| 236 | reg [3:0] next_state ; |
| 237 | // SM state register |
| 238 | reg [3:0] cur_state ; |
| 239 | |
| 240 | // variables for indicating which state state machine is in |
| 241 | // this variables are used to reduce logic levels in case of heavily constrained PCI signals |
| 242 | reg sm_idle ; |
| 243 | reg sm_address ; |
| 244 | reg sm_data_phases ; |
| 245 | reg sm_turn_arround ; |
| 246 | |
| 247 | // state machine register control logic with clock enable |
| 248 | always@(posedge reset_in or posedge clk_in) |
| 249 | begin |
| 250 | if (reset_in) |
| 251 | cur_state <= #`FF_DELAY S_IDLE ; |
| 252 | else |
| 253 | if ( change_state ) |
| 254 | cur_state <= #`FF_DELAY next_state ; |
| 255 | end |
| 256 | |
| 257 | // parameters - data selector - ad and bc lines switch between address/data and bus command/byte enable respectively |
| 258 | parameter SEL_ADDR_BC = 2'b01 ; |
| 259 | parameter SEL_DATA_BE = 2'b00 ; |
| 260 | parameter SEL_NEXT_DATA_BE = 2'b11 ; |
| 261 | |
| 262 | reg [1:0] wdata_selector ; |
| 263 | |
| 264 | wire u_dont_have_pci_bus = pci_gnt_in || ~pci_frame_in || ~pci_irdy_in ; // pci master can't start a transaction when GNT is deasserted ( 1 ) or |
| 265 | // bus is not in idle state ( FRAME and IRDY both 1 ) |
| 266 | wire u_have_pci_bus = ~pci_gnt_in && pci_frame_in && pci_irdy_in ; |
| 267 | |
| 268 | // decode count enable - counter that counts cycles passed since address phase |
| 269 | wire sm_decode_count_enable = sm_data_phases ; // counter is enabled when master wants to transfer |
| 270 | wire decode_count_enable = sm_decode_count_enable && pci_trdy_in && pci_stop_in && pci_devsel_in ; // and target is not responding |
| 271 | wire decode_count_load = ~decode_count_enable ; |
| 272 | reg [2:0] decode_count ; |
| 273 | |
| 274 | wire decode_to = ~( decode_count[2] || decode_count[1]) ; |
| 275 | |
| 276 | always@(posedge reset_in or posedge clk_in) |
| 277 | begin |
| 278 | if ( reset_in ) |
| 279 | // initial value of counter is 4 |
| 280 | decode_count <= #`FF_DELAY 3'h4 ; |
| 281 | else |
| 282 | if ( decode_count_load ) |
| 283 | decode_count <= #`FF_DELAY 3'h4 ; |
| 284 | else |
| 285 | if ( decode_count_enable ) |
| 286 | decode_count <= #`FF_DELAY decode_count - 1'b1 ; |
| 287 | end |
| 288 | |
| 289 | // Bus commands LSbit indicates whether operation is a read or a write |
| 290 | wire do_write = bc_in[0] ; |
| 291 | |
| 292 | // latency timer |
| 293 | reg [7:0] latency_timer ; |
| 294 | |
| 295 | wire latency_time_out = ~( |
| 296 | (latency_timer[7] || latency_timer[6] || latency_timer[5] || latency_timer[4]) || |
| 297 | (latency_timer[3] || latency_timer[2] || latency_timer[1] ) |
| 298 | ) ; |
| 299 | |
| 300 | wire latency_timer_enable = (sm_address || sm_data_phases) && ~latency_time_out ; |
| 301 | wire latency_timer_load = ~sm_address && ~sm_data_phases ; |
| 302 | |
| 303 | always@(posedge clk_in or posedge reset_in) |
| 304 | begin |
| 305 | if (reset_in) |
| 306 | latency_timer <= #`FF_DELAY 8'h00 ; |
| 307 | else |
| 308 | if ( latency_timer_load ) |
| 309 | latency_timer <= #`FF_DELAY latency_tim_val_in ; |
| 310 | else |
| 311 | if ( latency_timer_enable) // latency timer counts down until it expires - then it stops |
| 312 | latency_timer <= #`FF_DELAY latency_timer - 1'b1 ; |
| 313 | end |
| 314 | |
| 315 | // master abort indicators - when decode time out occurres and still no target response is received |
| 316 | wire do_master_abort = decode_to && pci_trdy_in && pci_stop_in && pci_devsel_in ; |
| 317 | reg mabort1 ; |
| 318 | always@(posedge reset_in or posedge clk_in) |
| 319 | begin |
| 320 | if (reset_in) |
| 321 | mabort1 <= #`FF_DELAY 1'b0 ; |
| 322 | else |
| 323 | mabort1 <= #`FF_DELAY do_master_abort ; |
| 324 | end |
| 325 | |
| 326 | reg mabort2 ; |
| 327 | always@(posedge reset_in or posedge clk_in) |
| 328 | begin |
| 329 | if ( reset_in ) |
| 330 | mabort2 <= #`FF_DELAY 1'b0 ; |
| 331 | else |
| 332 | mabort2 <= #`FF_DELAY mabort1 ; |
| 333 | end |
| 334 | |
| 335 | // master abort is only asserted for one clock cycle |
| 336 | assign mabort_out = mabort1 && ~mabort2 ; |
| 337 | |
| 338 | // register indicating when master should do timeout termination (latency timer expires) |
| 339 | reg timeout ; |
| 340 | always@(posedge reset_in or posedge clk_in) |
| 341 | begin |
| 342 | if (reset_in) |
| 343 | timeout <= #`FF_DELAY 1'b0 ; |
| 344 | else |
| 345 | timeout <= #`FF_DELAY (latency_time_out && ~pci_frame_out_in && pci_gnt_in || timeout ) && ~wait_out ; |
| 346 | end |
| 347 | |
| 348 | wire timeout_termination = sm_turn_arround && timeout && pci_stop_reg_in ; |
| 349 | |
| 350 | // frame control logic |
| 351 | // frame is forced to 0 (active) when state machine is in idle state, since only possible next state is address state which always drives frame active |
| 352 | wire force_frame = ~sm_idle ; |
| 353 | // slow signal for frame calculated from various registers in the core |
| 354 | wire slow_frame = last_in || (latency_time_out && pci_gnt_in) || (next_last_in && sm_data_phases) || mabort1 ; |
| 355 | // critical timing frame logic in separate module - some combinations of target signals force frame to inactive state immediately after sampled asserted |
| 356 | // (STOP) |
| 357 | pci_frame_crit frame_iob_feed |
| 358 | ( |
| 359 | .pci_frame_out (pci_frame_out), |
| 360 | .force_frame_in (force_frame), |
| 361 | .slow_frame_in (slow_frame), |
| 362 | .pci_stop_in (pci_stop_in) |
| 363 | ) ; |
| 364 | |
| 365 | // frame IOB flip flop's clock enable signal |
| 366 | // slow clock enable - calculated from internal - non critical paths |
| 367 | wire frame_load_slow = sm_idle || sm_address || mabort1 ; |
| 368 | |
| 369 | // critical clock enable for frame IOB in separate module - target response signals actually allow frame value change - critical timing |
| 370 | pci_frame_load_crit frame_iob_ce |
| 371 | ( |
| 372 | .pci_frame_load_out (pci_frame_load_out), |
| 373 | .sm_data_phases_in (sm_data_phases), |
| 374 | .frame_load_slow_in (frame_load_slow), |
| 375 | .pci_trdy_in (pci_trdy_in), |
| 376 | .pci_stop_in (pci_stop_in) |
| 377 | ) ; |
| 378 | |
| 379 | // IRDY driving |
| 380 | // non critical path for IRDY calculation |
| 381 | wire irdy_slow = pci_frame_out_in && mabort1 || mabort2 ; |
| 382 | |
| 383 | // critical path in separate module |
| 384 | pci_irdy_out_crit irdy_iob_feed |
| 385 | ( |
| 386 | .pci_irdy_out (pci_irdy_out), |
| 387 | .irdy_slow_in (irdy_slow), |
| 388 | .pci_frame_out_in (pci_frame_out_in), |
| 389 | .pci_trdy_in (pci_trdy_in), |
| 390 | .pci_stop_in (pci_stop_in) |
| 391 | ) ; |
| 392 | |
| 393 | // transfer FF indicator - when first transfer occurs it is set to 1 so backend can distinguish between disconnects and retries. |
| 394 | wire sm_transfer = sm_data_phases ; |
| 395 | reg transfer ; |
| 396 | |
| 397 | wire transfer_input = sm_transfer && (~(pci_trdy_in || pci_devsel_in) || transfer) ; |
| 398 | |
| 399 | always@(posedge clk_in or posedge reset_in) |
| 400 | begin |
| 401 | if (reset_in) |
| 402 | transfer <= #`FF_DELAY 1'b0 ; |
| 403 | else |
| 404 | transfer <= #`FF_DELAY transfer_input ; |
| 405 | end |
| 406 | |
| 407 | assign first_out = ~transfer ; |
| 408 | |
| 409 | // fast transfer status output - it's only negated target ready, since wait indicator qualifies valid transfer |
| 410 | assign wtransfer_out = ~pci_trdy_in ; |
| 411 | |
| 412 | // registered transfer status output - calculated from registered target response inputs |
| 413 | assign rtransfer_out = ~(pci_trdy_reg_in || pci_devsel_reg_in) ; |
| 414 | |
| 415 | // registered error status - calculated from registered target response inputs |
| 416 | assign rerror_out = (~pci_stop_reg_in && pci_devsel_reg_in) ; |
| 417 | |
| 418 | // retry is signalled to backend depending on registered target response or when latency timer expires |
| 419 | assign retry_out = timeout_termination || (~pci_stop_reg_in && ~pci_devsel_reg_in) ; |
| 420 | |
| 421 | // AD output flip flops' clock enable |
| 422 | // new data is loaded to AD outputs whenever state machine is idle, bus was granted and bus is in idle state or |
| 423 | // when address phase is about to be finished |
| 424 | wire ad_load_slow = sm_address ; |
| 425 | wire ad_load_on_grant = sm_idle && pci_frame_in && pci_irdy_in ; |
| 426 | |
| 427 | pci_mas_ad_load_crit mas_ad_load_feed |
| 428 | ( |
| 429 | .ad_load_out (ad_load_out), |
| 430 | .ad_load_in (ad_load_slow), |
| 431 | .ad_load_on_grant_in (ad_load_on_grant), |
| 432 | .pci_gnt_in (pci_gnt_in) |
| 433 | ); |
| 434 | |
| 435 | // next data loading is allowed when state machine is in transfer state and operation is a write |
| 436 | assign ad_load_on_transfer_out = sm_data_phases && do_write ; |
| 437 | |
| 438 | // request for a bus is issued anytime when backend is requesting a transaction and state machine is in idle state |
| 439 | assign pci_req_out = ~(req_in && sm_idle) ; |
| 440 | |
| 441 | // change state signal is actually clock enable for state register |
| 442 | // Non critical path for state change enable: |
| 443 | // state is always changed when: |
| 444 | // - address phase is finishing |
| 445 | // - state machine is in turn arround state |
| 446 | // - state machine is in transfer state and master abort termination is in progress |
| 447 | |
| 448 | wire ch_state_slow = sm_address || sm_turn_arround || sm_data_phases && ( pci_frame_out_in && mabort1 || mabort2 ) ; |
| 449 | |
| 450 | // a bit more critical change state enable is calculated with GNT signal |
| 451 | wire ch_state_med = ch_state_slow || sm_idle && u_have_pci_bus && req_in && rdy_in ; |
| 452 | |
| 453 | // most critical change state enable - calculated from target response signals |
| 454 | pci_mas_ch_state_crit state_machine_ce |
| 455 | ( |
| 456 | .change_state_out (change_state), |
| 457 | .ch_state_med_in (ch_state_med), |
| 458 | .sm_data_phases_in (sm_data_phases), |
| 459 | .pci_trdy_in (pci_trdy_in), |
| 460 | .pci_stop_in (pci_stop_in) |
| 461 | ) ; |
| 462 | |
| 463 | // ad enable driving |
| 464 | // also divided in several categories - from less critical to most critical in separate module |
| 465 | //wire ad_en_slowest = do_write && (sm_address || sm_data_phases && ~pci_frame_out_in) ; |
| 466 | //wire ad_en_on_grant = sm_idle && pci_frame_in && pci_irdy_in || sm_turn_arround ; |
| 467 | //wire ad_en_slow = ad_en_on_grant && ~pci_gnt_in || ad_en_slowest ; |
| 468 | //wire ad_en_keep = sm_data_phases && do_write && (pci_frame_out_in && ~mabort1 && ~mabort2) ; |
| 469 | |
| 470 | wire ad_en_slow = do_write && ( sm_address || ( sm_data_phases && !( ( pci_frame_out_in && mabort1 ) || mabort2 ) ) ) ; |
| 471 | wire ad_en_on_grant = ( sm_idle && pci_frame_in && pci_irdy_in ) || sm_turn_arround ; |
| 472 | |
| 473 | // critical timing ad enable - calculated from grant input |
| 474 | pci_mas_ad_en_crit ad_iob_oe_feed |
| 475 | ( |
| 476 | .pci_ad_en_out (pci_ad_en_out), |
| 477 | .ad_en_slow_in (ad_en_slow), |
| 478 | .ad_en_on_grant_in (ad_en_on_grant), |
| 479 | .pci_gnt_in (pci_gnt_in) |
| 480 | ) ; |
| 481 | |
| 482 | // cbe enable driving |
| 483 | wire cbe_en_on_grant = sm_idle && pci_frame_in && pci_irdy_in || sm_turn_arround ; |
| 484 | wire cbe_en_slow = cbe_en_on_grant && ~pci_gnt_in || sm_address || sm_data_phases && ~pci_frame_out_in ; |
| 485 | wire cbe_en_keep = sm_data_phases && pci_frame_out_in && ~mabort1 && ~mabort2 ; |
| 486 | |
| 487 | // most critical cbe enable in separate module - calculated with most critical target inputs |
| 488 | pci_cbe_en_crit cbe_iob_feed |
| 489 | ( |
| 490 | .pci_cbe_en_out (pci_cbe_en_out), |
| 491 | .cbe_en_slow_in (cbe_en_slow), |
| 492 | .cbe_en_keep_in (cbe_en_keep), |
| 493 | .pci_stop_in (pci_stop_in), |
| 494 | .pci_trdy_in (pci_trdy_in) |
| 495 | |
| 496 | ) ; |
| 497 | |
| 498 | // IRDY enable is equal to FRAME enable delayed for one clock |
| 499 | assign pci_irdy_en_out = pci_frame_en_in ; |
| 500 | |
| 501 | // frame enable driving - sometimes it's calculated from non critical paths |
| 502 | wire frame_en_slow = (sm_idle && u_have_pci_bus && req_in && rdy_in) || sm_address || (sm_data_phases && ~pci_frame_out_in) ; |
| 503 | wire frame_en_keep = sm_data_phases && pci_frame_out_in && ~mabort1 && ~mabort2 ; |
| 504 | |
| 505 | // most critical frame enable - calculated from heavily constrained target inputs in separate module |
| 506 | pci_frame_en_crit frame_iob_en_feed |
| 507 | ( |
| 508 | .pci_frame_en_out (pci_frame_en_out), |
| 509 | .frame_en_slow_in (frame_en_slow), |
| 510 | .frame_en_keep_in (frame_en_keep), |
| 511 | .pci_stop_in (pci_stop_in), |
| 512 | .pci_trdy_in (pci_trdy_in) |
| 513 | ) ; |
| 514 | |
| 515 | // state machine next state definitions |
| 516 | always@( |
| 517 | cur_state or |
| 518 | do_write or |
| 519 | pci_frame_out_in |
| 520 | ) |
| 521 | begin |
| 522 | // default values for state machine outputs |
| 523 | wait_out = 1'b1 ; |
| 524 | wdata_selector = SEL_ADDR_BC ; |
| 525 | sm_idle = 1'b0 ; |
| 526 | sm_address = 1'b0 ; |
| 527 | sm_data_phases = 1'b0 ; |
| 528 | sm_turn_arround = 1'b0 ; |
| 529 | |
| 530 | case ( cur_state ) |
| 531 | |
| 532 | S_IDLE: begin |
| 533 | // indicate the state |
| 534 | sm_idle = 1'b1 ; |
| 535 | // assign next state - only possible is address - if state machine is supposed to stay in idle state |
| 536 | // outside signals disable the clock |
| 537 | next_state = S_ADDRESS ; |
| 538 | wdata_selector = SEL_DATA_BE ; |
| 539 | end |
| 540 | |
| 541 | S_ADDRESS: begin |
| 542 | // indicate the state |
| 543 | sm_address = 1'b1 ; |
| 544 | // select appropriate data/be for outputs |
| 545 | wdata_selector = SEL_NEXT_DATA_BE ; |
| 546 | // only possible next state is transfer state |
| 547 | next_state = S_TRANSFER ; |
| 548 | end |
| 549 | |
| 550 | S_TRANSFER: begin |
| 551 | // during transfers wait indicator is inactive - all status signals are now valid |
| 552 | wait_out = 1'b0 ; |
| 553 | // indicate the state |
| 554 | sm_data_phases = 1'b1 ; |
| 555 | // select appropriate data/be for outputs |
| 556 | wdata_selector = SEL_NEXT_DATA_BE ; |
| 557 | if ( pci_frame_out_in ) |
| 558 | begin |
| 559 | // when frame is inactive next state will be turn arround |
| 560 | next_state = S_TA_END ; |
| 561 | end |
| 562 | else |
| 563 | // while frame is active state cannot be anything else then transfer |
| 564 | next_state = S_TRANSFER ; |
| 565 | end |
| 566 | |
| 567 | S_TA_END: begin |
| 568 | // wait is still inactive because of registered statuses |
| 569 | wait_out = 1'b0 ; |
| 570 | // indicate the state |
| 571 | sm_turn_arround = 1'b1 ; |
| 572 | // next state is always idle |
| 573 | next_state = S_IDLE ; |
| 574 | end |
| 575 | default: next_state = S_IDLE ; |
| 576 | endcase |
| 577 | end |
| 578 | |
| 579 | // ad and cbe lines multiplexer for write data |
| 580 | reg [1:0] rdata_selector ; |
| 581 | always@(posedge clk_in or posedge reset_in) |
| 582 | begin |
| 583 | if ( reset_in ) |
| 584 | rdata_selector <= #`FF_DELAY SEL_ADDR_BC ; |
| 585 | else |
| 586 | if ( change_state ) |
| 587 | rdata_selector <= #`FF_DELAY wdata_selector ; |
| 588 | end |
| 589 | |
| 590 | always@(rdata_selector or address_in or bc_in or data_in or be_in or next_data_in or next_be_in) |
| 591 | begin |
| 592 | case ( rdata_selector ) |
| 593 | SEL_ADDR_BC: begin |
| 594 | pci_ad_out = address_in ; |
| 595 | pci_cbe_out = bc_in ; |
| 596 | end |
| 597 | |
| 598 | SEL_DATA_BE: begin |
| 599 | pci_ad_out = data_in ; |
| 600 | pci_cbe_out = be_in ; |
| 601 | end |
| 602 | SEL_NEXT_DATA_BE, |
| 603 | 2'b10: begin |
| 604 | pci_ad_out = next_data_in ; |
| 605 | pci_cbe_out = next_be_in ; |
| 606 | end |
| 607 | endcase |
| 608 | end |
| 609 | |
| 610 | // data output mux for reads |
| 611 | always@(mabort_out or pci_ad_reg_in) |
| 612 | begin |
| 613 | if ( mabort_out ) |
| 614 | data_out = 32'hFFFF_FFFF ; |
| 615 | else |
| 616 | data_out = pci_ad_reg_in ; |
| 617 | end |
| 618 | endmodule |