| 1 | // ========== Copyright Header Begin ========================================== |
| 2 | // |
| 3 | // OpenSPARC T2 Processor File: pcs_link_config.v |
| 4 | // Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved |
| 5 | // 4150 Network Circle, Santa Clara, California 95054, U.S.A. |
| 6 | // |
| 7 | // * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| 8 | // |
| 9 | // This program is free software; you can redistribute it and/or modify |
| 10 | // it under the terms of the GNU General Public License as published by |
| 11 | // the Free Software Foundation; version 2 of the License. |
| 12 | // |
| 13 | // This program is distributed in the hope that it will be useful, |
| 14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 16 | // GNU General Public License for more details. |
| 17 | // |
| 18 | // You should have received a copy of the GNU General Public License |
| 19 | // along with this program; if not, write to the Free Software |
| 20 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 21 | // |
| 22 | // For the avoidance of doubt, and except that if any non-GPL license |
| 23 | // choice is available it will apply instead, Sun elects to use only |
| 24 | // the General Public License version 2 (GPLv2) at this time for any |
| 25 | // software where a choice of GPL license versions is made |
| 26 | // available with the language indicating that GPLv2 or any later version |
| 27 | // may be used, or where a choice of which version of the GPL is applied is |
| 28 | // otherwise unspecified. |
| 29 | // |
| 30 | // Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
| 31 | // CA 95054 USA or visit www.sun.com if you need additional information or |
| 32 | // have any questions. |
| 33 | // |
| 34 | // ========== Copyright Header End ============================================ |
| 35 | // @(#)pcs_link_config.v 1.6G |
| 36 | /**********************************************************************/ |
| 37 | /* Project Name : CASSINI */ |
| 38 | /* Module Name : PCS Link Configuration */ |
| 39 | /* Description : This block performs the link configuration */ |
| 40 | /* procedure. Based on inputs from the Sequence */ |
| 41 | /* detection module, it determines whether the link */ |
| 42 | /* is up or not. This block also provides control */ |
| 43 | /* to the Tx out mux to mux out the proper control */ |
| 44 | /* symbols during link configuration. It allows */ |
| 45 | /* data from the encoder to pass through when the */ |
| 46 | /* link is up. */ |
| 47 | /* */ |
| 48 | /* If word synchronization is lost, the autonegot- */ |
| 49 | /* iation is restarted and the link config state */ |
| 50 | /* machine will only send C ordered sets until */ |
| 51 | /* synchronization is achieved again. Word sync */ |
| 52 | /* is lost when loss of signal is detected. Link */ |
| 53 | /* up local signal only transitions on even */ |
| 54 | /* boundaries. */ |
| 55 | /* */ |
| 56 | /* Assumptions : none. */ |
| 57 | /* */ |
| 58 | /* Parent module : pcs.v */ |
| 59 | /* Child modules : none. */ |
| 60 | /* Author Name : Linda Chen */ |
| 61 | /* Date Created : 10/15/96 */ |
| 62 | /* */ |
| 63 | /* Copyright (c) 1994, Sun Microsystems, Inc. */ |
| 64 | /* Sun Proprietary and Confidential */ |
| 65 | /* */ |
| 66 | /* Modifications : */ |
| 67 | /* 8/6/98 - change the autonegotiation so that */ |
| 68 | /* breaklink is exited despite no C codes received */ |
| 69 | /* 1/17/02 : added LT_TM related logic */ |
| 70 | /* from the link partner */ |
| 71 | /* Synthesis Notes : none yet */ |
| 72 | /**********************************************************************/ |
| 73 | |
| 74 | `include "pcs_define.h" |
| 75 | |
| 76 | module pcs_link_config (// inputs |
| 77 | txclk,reset_pci,res_auto_pci, |
| 78 | loss_sync_rx,pos_disp_tx_p, |
| 79 | good3_Cnack_rx,good3_CorData_rx, |
| 80 | got_C_rx,CorData_err_rx, |
| 81 | autoneg_ena_pci,serdes_rdy, |
| 82 | got3_config0_rx,timer_override_pci, |
| 83 | lost_link_pci,set_lol_from_los_pci, |
| 84 | set_lol_from_c_pci, |
| 85 | link_up_filter_en, |
| 86 | // outputs |
| 87 | link_up_loc,link_up_tx, |
| 88 | tx_enc_conf_sel,txd_sel,reset_tx, |
| 89 | ack,odd_tx,res_auto_tx, |
| 90 | link_state_tx,an_loss_sync, |
| 91 | lost_link_tx,set_lol_from_los_tx, |
| 92 | set_lol_from_c_tx,link_not_up_diag_tx); |
| 93 | |
| 94 | input txclk; // Tx Clk 125 MHz |
| 95 | input reset_pci; // hw and sw reset OR'ed, needs sync from PCI |
| 96 | input res_auto_pci; // from MII Config, needs sync from PCI |
| 97 | input loss_sync_rx; // indication of word sync status |
| 98 | input pos_disp_tx_p; // running disparity from encoder |
| 99 | input good3_Cnack_rx; // received 3 sequential and identical Config |
| 100 | // regs, disregard ack bit, needs sync from Rx |
| 101 | input good3_CorData_rx; // received 3 sequential and identical Config |
| 102 | // regs or data, needs sync from Rx |
| 103 | input got_C_rx; // last received or receiving Link Config set |
| 104 | input CorData_err_rx; // not receiving Config regs or good data |
| 105 | input autoneg_ena_pci; // enable for autonegotiation from MII config |
| 106 | input serdes_rdy; // from slink control block |
| 107 | input got3_config0_rx; // flag used to trigger restart of config |
| 108 | input timer_override_pci; // make timer short for speedy bringup |
| 109 | input lost_link_pci; // used to clear lost_link_tx register |
| 110 | input set_lol_from_los_pci; // clears diag bit for why link was lost |
| 111 | input set_lol_from_c_pci; // clears diag bit for why link was lost |
| 112 | input link_up_filter_en; |
| 113 | output link_up_loc; // a signal to the MII status register |
| 114 | output link_up_tx; // a signal to the MII status register |
| 115 | output [3:0] tx_enc_conf_sel; // encoder control lines |
| 116 | output [1:0] txd_sel; // select for tx data mux |
| 117 | output reset_tx; // synchronous reset to txclk |
| 118 | output ack; // used in configuration register sent |
| 119 | output odd_tx; // odd polarity for tx |
| 120 | output res_auto_tx; // synchronized version of restart_autoneg |
| 121 | output [3:0] link_state_tx; // link configuration state bits to slave |
| 122 | output an_loss_sync; // lost sync for over 10 ms, use to reinit |
| 123 | // serdes part |
| 124 | output lost_link_tx; // used to set link status bit |
| 125 | output set_lol_from_los_tx; // sets diag bit for why link was lost |
| 126 | output set_lol_from_c_tx; // sets diag bit for why link was lost |
| 127 | output [5:0] link_not_up_diag_tx;// gives reasons for why link not up |
| 128 | |
| 129 | wire reset_tx; // synchronized version of reset to rxclk |
| 130 | wire [3:0] link_state_tx, // link config state machine |
| 131 | nxt_link_state_tx; |
| 132 | wire error, nxt_error; // flag for incorrect character reception |
| 133 | wire res_auto_1shot; // 1 shot for restart auto config |
| 134 | wire res_auto_tx_d; // synchronized version of restart_autoneg del |
| 135 | wire got_C_tx; // synchronized version of got_C |
| 136 | wire CorData_err_tx; // synchronized version of CorData_err_rx |
| 137 | wire good3_Cnack_tx; // synchronized version of good3_Cnack_rx |
| 138 | wire good3_CorData_tx; // synchronized version of good3_CorData_rx |
| 139 | wire loss_sync_oneshot; // pulse for loss of sync, to trigger autneg |
| 140 | wire loss_sync_tx; // loss_sync synchronized |
| 141 | wire loss_sync_tx_d; // loss_sync synchronized and delayed |
| 142 | wire set_err, clr_err; // control for temp error register |
| 143 | wire ack; // used in configuration register sent |
| 144 | wire conf_polarity; // which polarity of config reg last sent |
| 145 | wire nxt_conf_polarity; // which polarity of config reg last sent |
| 146 | wire flip_conf_polarity; // signal used to flip config polarity flag |
| 147 | wire autoneg_ena_tx; // synchronized autonegotiation enable |
| 148 | wire [2:0] nxt_an_timer, // timer value |
| 149 | an_timer; // timer value |
| 150 | wire an_timer_done; // timer equals 12 ms - 16 ms |
| 151 | wire timer_tick; // one shot version of slow clk |
| 152 | wire start_timer; // initialize timer pulse |
| 153 | wire breaklink, // marks progress of autonegotiation |
| 154 | nxt_breaklink; // marks progress of autonegotiation |
| 155 | wire got3_config0_tx; // flag for restart an, synchronized |
| 156 | wire [2:0] nxt_los_timer, // count for 10 ms loss of sync timeout |
| 157 | los_timer; // count for 10 ms loss of sync timeout |
| 158 | wire los_timer_done; // timer equals 12 ms - 16 ms |
| 159 | wire nxt_restart_an, // flag to restart aneg |
| 160 | restart_an; // flag to restart aneg |
| 161 | wire slow_clk, // 4.2 ms clk |
| 162 | slow_clk_d; // 4.2 ms clk one txclk delayed |
| 163 | wire begin_an; // flag to clear restart an flag |
| 164 | wire timer_override_tx; // synchronized version of timer_override_pci |
| 165 | wire nxt_lost_link; // used to generate lost_link_tx signal |
| 166 | wire clr_lost_link; // used to generate lost_link_tx signal |
| 167 | wire set_lost_link; // used to generate lost_link_tx signal |
| 168 | wire nxt_set_lol_from_los; // for diagnostic flag why link was lost |
| 169 | wire nxt_set_lol_from_c; // for diagnostic flag why link was lost |
| 170 | wire clr_lol_from_los; // for diagnostic flag why link was lost |
| 171 | wire clr_lol_from_c; // for diagnostic flag why link was lost |
| 172 | wire set_restart_onC; // for lol_from_c diag flag |
| 173 | wire an_loss_sync_d; // used for diag bit creation to prevent |
| 174 | // bit high after read from reg |
| 175 | wire an_los_1shot; // one shot used for diag bit creation |
| 176 | wire link_up_loc_ori; // used for detecting link down |
| 177 | wire link_up_loc_ori_temp; // used for detecting link down before filtering |
| 178 | wire serdes_rdy_tx; // synchronized version of serdes_rdy in tx |
| 179 | // clock domain |
| 180 | wire link_up_tx; |
| 181 | |
| 182 | parameter LINK_NA = 4'h0, |
| 183 | LINK_CNACK2 = 4'h1, |
| 184 | LINK_CNACK3 = 4'h2, |
| 185 | LINK_CNACK4 = 4'h3, |
| 186 | LINK_CORDATA1 = 4'h4, |
| 187 | LINK_CORDATA2 = 4'h5, |
| 188 | LINK_CORDATA3 = 4'h6, |
| 189 | LINK_CORDATA4 = 4'h7, |
| 190 | CHECK_DISP = 4'h8, |
| 191 | FLIP_DISP = 4'h9, |
| 192 | LINK_UP_US = 4'hA, |
| 193 | LINK_UP_BOTH = 4'hB; |
| 194 | |
| 195 | /* |
| 196 | ** An LFSR is used to create a 50% duty cycle clock which has a |
| 197 | ** 4.2 ms cycle time. This is used by the loss of sync and the |
| 198 | ** autonegotiation timers which count to a value between 12.6 and |
| 199 | ** 16.8 ms. This is within the 10 - 20 ms window required. |
| 200 | */ |
| 201 | pcs_lfsr pcs_lfsr(txclk,timer_override_tx,reset_tx,slow_clk); |
| 202 | |
| 203 | assign |
| 204 | nxt_error = (reset_tx|clr_err)? 1'h0 : (set_err)? 1'h1 : error, |
| 205 | nxt_conf_polarity = (reset_tx) ? 1'h0 : (flip_conf_polarity) ? |
| 206 | ~conf_polarity : conf_polarity, |
| 207 | loss_sync_oneshot = loss_sync_tx & !loss_sync_tx_d, |
| 208 | res_auto_1shot = !res_auto_tx_d & res_auto_tx, |
| 209 | timer_tick = slow_clk & ~slow_clk_d, // every 4.2 ms |
| 210 | nxt_an_timer = (start_timer | reset_tx) ? 3'h0 : |
| 211 | an_timer_done ? an_timer : (timer_tick)? |
| 212 | an_timer + 3'h1: an_timer, |
| 213 | nxt_los_timer = (loss_sync_oneshot | reset_tx) ? 3'h0 : |
| 214 | los_timer_done ? los_timer : (timer_tick)? |
| 215 | los_timer + 3'h1 : los_timer, |
| 216 | nxt_restart_an = (reset_tx | begin_an)? 1'h0: |
| 217 | (restart_an | res_auto_1shot | an_loss_sync), |
| 218 | an_loss_sync = (los_timer_done & loss_sync_tx & ~loss_sync_oneshot), |
| 219 | an_los_1shot = an_loss_sync & ~an_loss_sync_d, |
| 220 | los_timer_done = (los_timer == 3'h4), // 12 -16 ms |
| 221 | an_timer_done = (an_timer == 3'h4), |
| 222 | set_lost_link = ~link_up_loc_ori & link_up_tx,// link_up_tx = link_up_loc_d |
| 223 | nxt_lost_link = (reset_tx) ? 1'b0: (set_lost_link)? 1'b1 : |
| 224 | (clr_lost_link)? 1'b0 : lost_link_tx, |
| 225 | nxt_set_lol_from_los = (reset_tx) ? 1'b0: (an_los_1shot)? (1'b1) : |
| 226 | (clr_lol_from_los)? 1'b0 : set_lol_from_los_tx, |
| 227 | nxt_set_lol_from_c = (reset_tx) ? 1'b0: (set_restart_onC)? (1'b1) : |
| 228 | (clr_lol_from_c)? 1'b0 : set_lol_from_c_tx, |
| 229 | link_up_loc = link_up_loc_ori | ~autoneg_ena_tx, // in manual mode allows tx ctrl to |
| 230 | // to send idles |
| 231 | link_not_up_diag_tx[0] = got3_config0_tx, |
| 232 | link_not_up_diag_tx[1] = !serdes_rdy_tx, |
| 233 | link_not_up_diag_tx[2] = !good3_Cnack_tx & ~link_up_loc, |
| 234 | link_not_up_diag_tx[3] = loss_sync_tx, |
| 235 | link_not_up_diag_tx[4] = !good3_CorData_tx &((link_state_tx == LINK_CORDATA1) |
| 236 | | (link_state_tx == LINK_CORDATA2) | (link_state_tx == LINK_CORDATA3) |
| 237 | | (link_state_tx == LINK_CORDATA4)), |
| 238 | link_not_up_diag_tx[5] = got_C_tx & (link_state_tx == LINK_UP_US), |
| 239 | |
| 240 | /* |
| 241 | ** Call of function link_config_fn |
| 242 | */ |
| 243 | {set_err,clr_err,ack,link_up_loc_ori_temp, |
| 244 | tx_enc_conf_sel,txd_sel,flip_conf_polarity, |
| 245 | start_timer,nxt_breaklink,begin_an, |
| 246 | set_restart_onC,nxt_link_state_tx} |
| 247 | = link_config_fn(reset_tx,restart_an,error, |
| 248 | good3_Cnack_tx,good3_CorData_tx,odd_tx, |
| 249 | CorData_err_tx,pos_disp_tx_p,loss_sync_tx, |
| 250 | conf_polarity,got_C_tx,autoneg_ena_tx, |
| 251 | serdes_rdy_tx,an_timer_done, |
| 252 | got3_config0_tx,breaklink,link_state_tx); |
| 253 | /* |
| 254 | ** Link Configuration state machine |
| 255 | */ |
| 256 | function [18:0] link_config_fn; |
| 257 | input reset; // reset |
| 258 | input restart_an; // trigger for autonegotiation restart |
| 259 | input error; // output of temporary error register |
| 260 | input good3_Cnack; // flag for 3 good C's no ack |
| 261 | input good3_CorData; // flag for 3 good C's or data |
| 262 | input odd; // this byte is odd flag |
| 263 | input CorData_err; // not receiving C sets or data |
| 264 | input pos_disp; // this data is positive disparity flag |
| 265 | input loss_sync; // prevents link up when loss_sync |
| 266 | input conf_polarity; // which polarity of config reg last sent |
| 267 | input got_C; // received Config sequence |
| 268 | input autoneg_ena; // enable autonegotiation from MII config |
| 269 | input serdes_rdy_tx; // serdes is initialized, rx clock recovered |
| 270 | input timer_done; // short timer reached terminal count |
| 271 | input got3_config0; // received Config Reg of zeros, break link |
| 272 | input breaklink; // stores what stage autoneg is in |
| 273 | input [3:0] state; |
| 274 | |
| 275 | reg set_err; // set temp error register |
| 276 | reg clr_err; // clear temp error register |
| 277 | reg ack; // ack bit of config register |
| 278 | reg link_up; // link is up |
| 279 | reg [3:0] tx_enc_conf_sel;// tx encoder control |
| 280 | reg [1:0] txd_sel; // tx data mux control |
| 281 | reg flip_config_polarity; // flips config reg polarity flag |
| 282 | reg start_timer; |
| 283 | reg nxt_breaklink; |
| 284 | reg begin_an; |
| 285 | reg set_restart_onC; |
| 286 | reg [3:0] n_state; // next state |
| 287 | |
| 288 | begin |
| 289 | set_err = 1'h0; // to catch all invalid codes - restart an |
| 290 | clr_err = 1'h0; |
| 291 | ack = 1'h0; |
| 292 | link_up = 1'h0; |
| 293 | tx_enc_conf_sel = `PCS_ENC_K285; |
| 294 | txd_sel = `PCS_TX_GMII_DATA; |
| 295 | flip_config_polarity = 1'h0; |
| 296 | start_timer = 1'h0; |
| 297 | nxt_breaklink = breaklink; |
| 298 | begin_an = 1'h0; |
| 299 | set_restart_onC = 1'h0; |
| 300 | n_state = 4'h0; |
| 301 | |
| 302 | case (state) |
| 303 | LINK_NA : // 0 |
| 304 | begin |
| 305 | if (~reset & odd & ~autoneg_ena & ~loss_sync & ~got_C) |
| 306 | begin |
| 307 | n_state = LINK_UP_BOTH; // enter on even |
| 308 | begin_an = 1'h1; |
| 309 | end |
| 310 | else if (~reset & ~odd & autoneg_ena) |
| 311 | n_state = LINK_CNACK2; // enter on odd |
| 312 | else // reset or disabled or odd |
| 313 | begin |
| 314 | n_state = LINK_NA; |
| 315 | tx_enc_conf_sel = `PCS_ENC_H_CHAR; |
| 316 | // to prevent rx sync on odd |
| 317 | start_timer = 1'h1; |
| 318 | set_err = loss_sync; |
| 319 | nxt_breaklink = 1'h1; |
| 320 | end |
| 321 | end |
| 322 | LINK_CNACK2 : // 1 |
| 323 | begin |
| 324 | set_err = loss_sync; |
| 325 | if (conf_polarity) |
| 326 | tx_enc_conf_sel = `PCS_ENC_LINK_CONFA; |
| 327 | else |
| 328 | tx_enc_conf_sel = `PCS_ENC_LINK_CONFB; |
| 329 | flip_config_polarity = 1'h1; |
| 330 | n_state = LINK_CNACK3; |
| 331 | end |
| 332 | LINK_CNACK3 : // 2 |
| 333 | begin |
| 334 | tx_enc_conf_sel = `PCS_ENC_DATA; |
| 335 | if (breaklink) |
| 336 | txd_sel = `PCS_TX_CONF_ZEROS; |
| 337 | else |
| 338 | txd_sel = `PCS_TX_CONF_REG1; |
| 339 | set_err = loss_sync; |
| 340 | n_state = LINK_CNACK4; |
| 341 | end |
| 342 | LINK_CNACK4 : // 3 |
| 343 | begin |
| 344 | tx_enc_conf_sel = `PCS_ENC_DATA; |
| 345 | if (breaklink) // break link |
| 346 | txd_sel = `PCS_TX_CONF_ZEROS; |
| 347 | else |
| 348 | txd_sel = `PCS_TX_CONF_REG2; |
| 349 | if (error) |
| 350 | begin |
| 351 | clr_err = 1'h1; |
| 352 | n_state = LINK_NA; |
| 353 | nxt_breaklink = 1'h1; |
| 354 | start_timer = 1'h1; |
| 355 | end |
| 356 | else if (breaklink & timer_done & serdes_rdy_tx) |
| 357 | begin // break link, promote |
| 358 | n_state = LINK_NA; |
| 359 | nxt_breaklink = 1'h0; |
| 360 | end |
| 361 | else if (~breaklink & good3_Cnack & ~got3_config0) |
| 362 | // base page, promote |
| 363 | begin |
| 364 | n_state = LINK_CORDATA1; |
| 365 | clr_err = 1'h1; |
| 366 | start_timer = 1'h1; |
| 367 | begin_an = 1'h1; |
| 368 | end |
| 369 | else |
| 370 | n_state = LINK_NA; |
| 371 | end |
| 372 | LINK_CORDATA1 : // 4 |
| 373 | begin |
| 374 | set_err = CorData_err | loss_sync; |
| 375 | n_state = LINK_CORDATA2; |
| 376 | end |
| 377 | LINK_CORDATA2 : // 5 |
| 378 | begin |
| 379 | set_err = CorData_err | loss_sync; |
| 380 | n_state = LINK_CORDATA3; |
| 381 | if (conf_polarity) |
| 382 | tx_enc_conf_sel = `PCS_ENC_LINK_CONFA; |
| 383 | else |
| 384 | tx_enc_conf_sel = `PCS_ENC_LINK_CONFB; |
| 385 | flip_config_polarity = 1'h1; |
| 386 | end |
| 387 | LINK_CORDATA3 : // 6 |
| 388 | begin |
| 389 | set_err = CorData_err | loss_sync; |
| 390 | tx_enc_conf_sel = `PCS_ENC_DATA; |
| 391 | txd_sel = `PCS_TX_CONF_REG1; |
| 392 | n_state = LINK_CORDATA4; |
| 393 | end |
| 394 | LINK_CORDATA4 : // 7 |
| 395 | begin |
| 396 | tx_enc_conf_sel = `PCS_ENC_DATA; |
| 397 | txd_sel = `PCS_TX_CONF_REG2; |
| 398 | ack = 1'h1; |
| 399 | if (error | got3_config0) |
| 400 | begin |
| 401 | clr_err = 1'h1; |
| 402 | n_state = LINK_NA; |
| 403 | nxt_breaklink = 1'h1; |
| 404 | start_timer = 1'h1; |
| 405 | end |
| 406 | else if (good3_CorData & timer_done) |
| 407 | begin |
| 408 | n_state = CHECK_DISP; |
| 409 | start_timer = 1'h1; |
| 410 | end |
| 411 | else |
| 412 | n_state = LINK_CORDATA1; // waiting for 3 good C's or Data |
| 413 | end |
| 414 | CHECK_DISP : // 8 |
| 415 | begin |
| 416 | nxt_breaklink = 1'h1; // reset for future use |
| 417 | if (pos_disp) // disp at output of encoder |
| 418 | n_state = FLIP_DISP; // K28.5 |
| 419 | else |
| 420 | begin |
| 421 | n_state = LINK_UP_US; |
| 422 | end |
| 423 | end |
| 424 | FLIP_DISP : // 9 |
| 425 | begin |
| 426 | tx_enc_conf_sel = `PCS_ENC_IDLE1; |
| 427 | n_state = LINK_UP_US; |
| 428 | end |
| 429 | LINK_UP_US : // A |
| 430 | begin |
| 431 | if ((restart_an | got3_config0) & odd) |
| 432 | n_state = LINK_NA; |
| 433 | else if (got_C | ~timer_done | ~odd) // flush incoming C's |
| 434 | n_state = LINK_UP_US; |
| 435 | else |
| 436 | begin |
| 437 | n_state = LINK_UP_BOTH; |
| 438 | end |
| 439 | if (odd) |
| 440 | tx_enc_conf_sel = `PCS_ENC_IDLE2; |
| 441 | end |
| 442 | LINK_UP_BOTH : // B |
| 443 | begin // always enter on even |
| 444 | tx_enc_conf_sel = `PCS_ENC_DATA; |
| 445 | if ((restart_an | good3_Cnack) & odd) // always exit on odd |
| 446 | begin |
| 447 | n_state = LINK_NA; |
| 448 | set_restart_onC = good3_Cnack; |
| 449 | end |
| 450 | |
| 451 | else |
| 452 | begin |
| 453 | link_up = 1'h1; |
| 454 | n_state = LINK_UP_BOTH; |
| 455 | end |
| 456 | end |
| 457 | endcase |
| 458 | |
| 459 | link_config_fn = {set_err,clr_err,ack, |
| 460 | link_up,tx_enc_conf_sel,txd_sel, |
| 461 | flip_config_polarity,start_timer, |
| 462 | nxt_breaklink,begin_an,set_restart_onC,n_state}; |
| 463 | end |
| 464 | endfunction |
| 465 | |
| 466 | RREG #(4) r_state (link_state_tx, txclk, reset_tx, |
| 467 | nxt_link_state_tx); |
| 468 | RREG #(1) r_odd_tx (odd_tx,txclk,reset_tx,~odd_tx); |
| 469 | REG #(1) r_error (error, txclk, nxt_error); |
| 470 | REG #(1) r_loss_sync_d (loss_sync_tx_d, txclk, loss_sync_tx); |
| 471 | REG #(1) r_conf_polarity(conf_polarity,txclk,nxt_conf_polarity); |
| 472 | REG #(1) r_res_auto_d(res_auto_tx_d,txclk,res_auto_tx); |
| 473 | REG #(1) r_link_up_tx (link_up_tx, txclk, link_up_loc_ori); // unglitch |
| 474 | REG #(3) r_an_timer(an_timer,txclk,nxt_an_timer); |
| 475 | REG #(3) r_los_timer(los_timer,txclk,nxt_los_timer); |
| 476 | REG #(1) r_slowclk(slow_clk_d,txclk,slow_clk); |
| 477 | REG #(1) r_lost_link_tx(lost_link_tx,txclk,nxt_lost_link); |
| 478 | RREG #(1) r_breaklink(breaklink,txclk,reset_tx,nxt_breaklink); |
| 479 | RREG #(1) r_restart_an(restart_an,txclk,reset_tx,nxt_restart_an); |
| 480 | REG #(1) r_set_lol_los (set_lol_from_los_tx,txclk,nxt_set_lol_from_los); |
| 481 | REG #(1) r_set_lol_c (set_lol_from_c_tx,txclk,nxt_set_lol_from_c); |
| 482 | REG #(1) r_an_los_1shot (an_loss_sync_d,txclk,an_loss_sync); |
| 483 | |
| 484 | // SYNCREG (qout, clk, din); |
| 485 | SYNCREG r_res_auto(res_auto_tx,txclk,res_auto_pci); |
| 486 | SYNCREG r_loss_sync_tx (loss_sync_tx, txclk, loss_sync_rx); |
| 487 | SYNCREG r_reset_tx (.qout(reset_tx),.clk(txclk),.din(reset_pci)); |
| 488 | |
| 489 | SYNCREG r_got_C (got_C_tx, txclk, got_C_rx); |
| 490 | SYNCREG r_autoneg_ena_tx (autoneg_ena_tx, txclk, autoneg_ena_pci); |
| 491 | SYNCREG r_CorData_err (CorData_err_tx, txclk, CorData_err_rx); |
| 492 | SYNCREG r_good3_Cnack (good3_Cnack_tx, txclk, good3_Cnack_rx); |
| 493 | SYNCREG r_good3_CorData (good3_CorData_tx, txclk, good3_CorData_rx); |
| 494 | SYNCREG r_got3_config0 (got3_config0_tx, txclk, got3_config0_rx); |
| 495 | SYNCREG r_timer_override (timer_override_tx, txclk, timer_override_pci); |
| 496 | SYNCREG r_clr_lost_link (clr_lost_link, txclk, lost_link_pci); |
| 497 | SYNCREG r_clr_lol_los (clr_lol_from_los, txclk,set_lol_from_los_pci); |
| 498 | SYNCREG r_clr_lol_c (clr_lol_from_c, txclk,set_lol_from_c_pci); |
| 499 | SYNCREG r_serdes_rdy_tx (serdes_rdy_tx,txclk,serdes_rdy); |
| 500 | |
| 501 | |
| 502 | /************************************************** |
| 503 | * Added link_up filter logic -loj @Nov. 1st 2005 |
| 504 | **************************************************/ |
| 505 | wire link_up_pls; |
| 506 | wire link_down_pls; |
| 507 | wire link_up_filter_en; |
| 508 | wire timer_on; |
| 509 | reg [10:0] timer_cnt; |
| 510 | |
| 511 | PlsGen2 PlsGen2(.sig_in(link_up_loc_ori_temp),.clk(txclk),.lead(link_up_pls),.trail(link_down_pls)); |
| 512 | |
| 513 | SRFF timer_on_SRFF(.reset(reset_tx),.clk(txclk),.iSet(link_up_pls),.iRst(link_down_pls),.oQ(timer_on)); |
| 514 | |
| 515 | always @ (posedge txclk) |
| 516 | if (reset_tx | (~timer_on)) |
| 517 | timer_cnt <= 0; |
| 518 | else if (timer_cnt[10]) |
| 519 | timer_cnt <= timer_cnt; |
| 520 | else timer_cnt <= timer_cnt + 1; |
| 521 | |
| 522 | |
| 523 | assign link_up_loc_ori = link_up_filter_en ? (timer_cnt[10] & link_up_loc_ori_temp) : link_up_loc_ori_temp; |
| 524 | |
| 525 | /* --------------- spare gates --------------- */ |
| 526 | `ifdef NEPTUNE |
| 527 | wire [3:0] do_nad; |
| 528 | wire [3:0] do_nor; |
| 529 | wire [3:0] do_inv; |
| 530 | wire [3:0] do_mux; |
| 531 | wire [3:0] do_q; |
| 532 | wire so; |
| 533 | |
| 534 | mac_spare_gates pcs_link_config_spare_gates ( |
| 535 | .di_nd3 ({1'h1, 1'h1, do_q[3]}), |
| 536 | .di_nd2 ({1'h1, 1'h1, do_q[2]}), |
| 537 | .di_nd1 ({1'h1, 1'h1, do_q[1]}), |
| 538 | .di_nd0 ({1'h1, 1'h1, do_q[0]}), |
| 539 | .di_nr3 ({1'h0, 1'h0}), |
| 540 | .di_nr2 ({1'h0, 1'h0}), |
| 541 | .di_nr1 ({1'h0, 1'h0}), |
| 542 | .di_nr0 ({1'h0, 1'h0}), |
| 543 | .di_inv (do_nad[3:0]), |
| 544 | .di_mx3 ({1'h0, 1'h0}), |
| 545 | .di_mx2 ({1'h0, 1'h0}), |
| 546 | .di_mx1 ({1'h0, 1'h0}), |
| 547 | .di_mx0 ({1'h0, 1'h0}), |
| 548 | .mx_sel (do_nor[3:0]), |
| 549 | .di_reg (do_inv[3:0]), |
| 550 | .wt_ena (do_mux[3:0]), |
| 551 | .rst ({4{reset_tx}}), |
| 552 | .si (1'h0), |
| 553 | .se (1'h0), |
| 554 | .clk (txclk), |
| 555 | .do_nad (do_nad[3:0]), |
| 556 | .do_nor (do_nor[3:0]), |
| 557 | .do_inv (do_inv[3:0]), |
| 558 | .do_mux (do_mux[3:0]), |
| 559 | .do_q (do_q[3:0]), |
| 560 | .so (so) |
| 561 | ); |
| 562 | |
| 563 | `else |
| 564 | `endif |
| 565 | |
| 566 | |
| 567 | endmodule |
| 568 | |