| 1 | // ========== Copyright Header Begin ========================================== |
| 2 | // |
| 3 | // OpenSPARC T2 Processor File: rx_mii_gmii.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 | /*%W% %G%*/ |
| 36 | |
| 37 | /************************************************************************* |
| 38 | * |
| 39 | * File Name : rx_mii_gmii |
| 40 | * Author Name : John Lo |
| 41 | * Description : txmac gmii interface logic |
| 42 | * Parent Module: xmac |
| 43 | * Child Module: |
| 44 | * Interface Mod: |
| 45 | * Date Created : 9/22/00 |
| 46 | * |
| 47 | * Copyright (c) 2002, Sun Microsystems, Inc. |
| 48 | * Sun Proprietary and Confidential |
| 49 | * |
| 50 | * Modification : |
| 51 | * |
| 52 | * Synthesis Notes by loj: from hold_rxc -> g2x_rxc, hold_rxd -> g2x_rxd |
| 53 | * are signal changing clk domain. They are |
| 54 | * placed here to be able to close to each |
| 55 | * other to meet timing when synthesis/layout |
| 56 | * time comes. |
| 57 | * |
| 58 | *************************************************************************/ |
| 59 | |
| 60 | `include "xmac.h" |
| 61 | |
| 62 | module rx_mii_gmii ( |
| 63 | rx_nbclk, |
| 64 | rx_reset_nbclk, |
| 65 | hw_reset_rxnbclk, |
| 66 | rxfifo_full_nbclk, |
| 67 | rx_enable_nbclk, |
| 68 | // mgmii loopback signals |
| 69 | mgmii_txd, |
| 70 | mgmii_tx_en, |
| 71 | mgmii_tx_err, |
| 72 | mii_mode, |
| 73 | gmii_mode, |
| 74 | mii_or_gmii_mode, |
| 75 | loopback, |
| 76 | // rx gmii signals |
| 77 | gmii_rxd, |
| 78 | gmii_rx_dv, |
| 79 | gmii_rx_err, |
| 80 | // outputs |
| 81 | inc_align_err_count_nbclk, |
| 82 | rx_heart_beat_timer, |
| 83 | rx_heart_beat_timer_reg, |
| 84 | hold_rxd, |
| 85 | hold_rx_dv, |
| 86 | hold_rx_err, |
| 87 | mgrlm_state |
| 88 | ); |
| 89 | |
| 90 | input rx_nbclk; |
| 91 | input rx_reset_nbclk; |
| 92 | input hw_reset_rxnbclk; |
| 93 | input rxfifo_full_nbclk; |
| 94 | input rx_enable_nbclk; |
| 95 | // mgmii loopback signals |
| 96 | input [`BYTE] mgmii_txd; |
| 97 | input mgmii_tx_en; |
| 98 | input mgmii_tx_err; |
| 99 | input mii_mode; |
| 100 | input gmii_mode; |
| 101 | input mii_or_gmii_mode; |
| 102 | input loopback; |
| 103 | // gmii signals |
| 104 | input [`BYTE] gmii_rxd; |
| 105 | input gmii_rx_dv; |
| 106 | input gmii_rx_err; |
| 107 | // outputs |
| 108 | output inc_align_err_count_nbclk; |
| 109 | output [3:0] rx_heart_beat_timer; // to clock mux |
| 110 | output [3:0] rx_heart_beat_timer_reg; |
| 111 | output [63:0] hold_rxd; |
| 112 | output [7:0] hold_rx_dv; |
| 113 | output hold_rx_err; |
| 114 | output mgrlm_state; |
| 115 | |
| 116 | reg [`BYTE] rxd_ilane7; // internal lane |
| 117 | reg [`BYTE] rxd_ilane6; // internal lane |
| 118 | reg [`BYTE] rxd_ilane5; // internal lane |
| 119 | reg [`BYTE] rxd_ilane4; // internal lane |
| 120 | reg [`BYTE] rxd_ilane3; // internal lane |
| 121 | reg [`BYTE] rxd_ilane2; // internal lane |
| 122 | reg [`BYTE] rxd_ilane1; // internal lane |
| 123 | reg [`BYTE] rxd_ilane0; // internal lane |
| 124 | reg [`NIB] rxd_ilaneX; // internal lane |
| 125 | reg rx_dv_ilane7; |
| 126 | reg rx_dv_ilane6; |
| 127 | reg rx_dv_ilane5; |
| 128 | reg rx_dv_ilane4; |
| 129 | reg rx_dv_ilane3; |
| 130 | reg rx_dv_ilane2; |
| 131 | reg rx_dv_ilane1; |
| 132 | reg rx_dv_ilane0; |
| 133 | reg rx_dv_ilane7a; |
| 134 | reg rx_dv_ilane6a; |
| 135 | reg rx_dv_ilane5a; |
| 136 | reg rx_dv_ilane4a; |
| 137 | reg rx_dv_ilane3a; |
| 138 | reg rx_dv_ilane2a; |
| 139 | reg rx_dv_ilane1a; |
| 140 | reg rx_dv_ilane0a; |
| 141 | reg rx_dv_ilaneX; |
| 142 | reg rx_err_ilane7; |
| 143 | reg rx_err_ilane6; |
| 144 | reg rx_err_ilane5; |
| 145 | reg rx_err_ilane4; |
| 146 | reg rx_err_ilane3; |
| 147 | reg rx_err_ilane2; |
| 148 | reg rx_err_ilane1; |
| 149 | reg rx_err_ilane0; |
| 150 | reg rx_err_ilane7a; |
| 151 | reg rx_err_ilane6a; |
| 152 | reg rx_err_ilane5a; |
| 153 | reg rx_err_ilane4a; |
| 154 | reg rx_err_ilane3a; |
| 155 | reg rx_err_ilane2a; |
| 156 | reg rx_err_ilane1a; |
| 157 | reg rx_err_ilane0a; |
| 158 | wire load_ok_state; |
| 159 | |
| 160 | // S = 8'hFB, T = 8'hFD, E = 8'hFE, I = 8'h07 |
| 161 | // in 802.3z pp-36A.2 shows PA => FB 55 55 55 55 55 55 D5 (big endian format) |
| 162 | // ^ |
| 163 | // detect SFD logic |
| 164 | // sfd is send out by rising edge clk. |
| 165 | |
| 166 | wire rx_det_sfd; |
| 167 | wire rx_det_eop_lv; |
| 168 | wire adjust_rx_heart_beat; // should be a pulse |
| 169 | wire rx_heart_beat; |
| 170 | wire hw_reset_rxnbclk_lead; |
| 171 | wire d_hw_reset_rxnbclk; |
| 172 | wire [`BYTE] g_rxd; |
| 173 | wire g_rx_err; |
| 174 | wire g_rx_err_lv; |
| 175 | wire mg_rx_dv_trail; |
| 176 | wire [`BYTE] mg_rxd; |
| 177 | wire mg_rx_dv; |
| 178 | wire mg_rx_err; |
| 179 | wire [`BYTE] mg_rxd_mux; |
| 180 | wire mg_rx_dv_mux; |
| 181 | wire mg_rx_err_mux; |
| 182 | wire rx_dv_ilane0_lead,rx_dv_ilaneX_lead,sfd_win; |
| 183 | |
| 184 | |
| 185 | // vlint flag_net_has_no_load off |
| 186 | // vlint flag_dangling_net_within_module off |
| 187 | wire rx_dv_ilane0_trail; |
| 188 | wire rx_dv_ilaneX_trail; |
| 189 | wire mg_rx_dv_lead; |
| 190 | // vlint flag_dangling_net_within_module on |
| 191 | // vlint flag_net_has_no_load on |
| 192 | |
| 193 | /* ------------ sfd qulification logic -------------------------- */ |
| 194 | |
| 195 | PlsGen2 rx_dv_ilane0_PlsGen2(.sig_in(rx_dv_ilane0),.clk(rx_nbclk), |
| 196 | .lead (rx_dv_ilane0_lead), |
| 197 | .trail (rx_dv_ilane0_trail)); |
| 198 | |
| 199 | PlsGen2 rx_dv_ilaneX_PlsGen2(.sig_in(rx_dv_ilaneX),.clk(rx_nbclk), |
| 200 | .lead (rx_dv_ilaneX_lead), |
| 201 | .trail (rx_dv_ilaneX_trail)); |
| 202 | |
| 203 | wire set_sfd_win = gmii_mode ? rx_dv_ilane0_lead : |
| 204 | rx_dv_ilaneX_lead ; |
| 205 | |
| 206 | |
| 207 | SRFF sfd_win_SRFF(.reset(rx_reset_nbclk),.clk(rx_nbclk), |
| 208 | .iSet(set_sfd_win), |
| 209 | .iRst(rx_det_sfd), |
| 210 | .oQ(sfd_win)); |
| 211 | |
| 212 | /* ---------- Data path ----------------------------------------- */ |
| 213 | |
| 214 | |
| 215 | RegDff #(8) g_rxd_RegDff (.din(gmii_rxd), .clk(rx_nbclk),.qout(g_rxd)); |
| 216 | RegDff #(1) mg_rx_dv_RegDff (.din(gmii_rx_dv), .clk(rx_nbclk),.qout(mg_rx_dv)); |
| 217 | RegDff #(1) mg_rx_err_RegDff(.din(gmii_rx_err),.clk(rx_nbclk),.qout(g_rx_err)); |
| 218 | |
| 219 | // Mainly to take care of the rx_err happend in pa time |
| 220 | RS_FF g_rx_err_lv_RS_FF (.set(g_rx_err), |
| 221 | .rst(mg_rx_dv_trail), |
| 222 | .clk(rx_nbclk), |
| 223 | .reset(rx_reset_nbclk), |
| 224 | .qout(g_rx_err_lv)); |
| 225 | |
| 226 | PlsGen2 mg_rx_dv_trail_PlsGen2(.sig_in(mg_rx_dv), |
| 227 | .clk(rx_nbclk), |
| 228 | .lead(mg_rx_dv_lead), |
| 229 | .trail(mg_rx_dv_trail)); |
| 230 | |
| 231 | assign mg_rx_err = mg_rx_dv & (g_rx_err | g_rx_err_lv); |
| 232 | assign mg_rxd = gmii_mode? g_rxd : {4'h0,g_rxd[`NIB]}; |
| 233 | assign mg_rxd_mux = loopback ? mgmii_txd : mg_rxd; |
| 234 | assign mg_rx_dv_mux = loopback ? mgmii_tx_en : mg_rx_dv; |
| 235 | assign mg_rx_err_mux= loopback ? mgmii_tx_err : mg_rx_err; |
| 236 | |
| 237 | |
| 238 | /* ---------- 1st stage: serial to paralle shifter --------------- */ |
| 239 | // rxd serial shifter |
| 240 | // rxd shifting is achieved by using `NIB0 to `NIB1. |
| 241 | // It is different from rx_dv which requires rx_dv_ilane?a. |
| 242 | |
| 243 | always @ (posedge rx_nbclk) |
| 244 | if (gmii_mode) |
| 245 | begin |
| 246 | rxd_ilane7 <= mg_rxd_mux[`BYTE]; |
| 247 | rxd_ilane6 <= rxd_ilane7; |
| 248 | rxd_ilane5 <= rxd_ilane6; |
| 249 | rxd_ilane4 <= rxd_ilane5; |
| 250 | rxd_ilane3 <= rxd_ilane4; |
| 251 | rxd_ilane2 <= rxd_ilane3; |
| 252 | rxd_ilane1 <= rxd_ilane2; |
| 253 | rxd_ilane0 <= rxd_ilane1; |
| 254 | rxd_ilaneX <= 0; |
| 255 | end |
| 256 | else // 10/100M mode; mii_mode |
| 257 | begin // rxd nibble shifting is achieved by using `NIB0 to `NIB1. |
| 258 | rxd_ilane7[`NIB0] <= mg_rxd_mux[`NIB]; |
| 259 | rxd_ilane7[`NIB1] <= rxd_ilane7[`NIB0]; |
| 260 | rxd_ilane6[`NIB0] <= rxd_ilane7[`NIB1]; |
| 261 | rxd_ilane6[`NIB1] <= rxd_ilane6[`NIB0]; |
| 262 | rxd_ilane5[`NIB0] <= rxd_ilane6[`NIB1]; |
| 263 | rxd_ilane5[`NIB1] <= rxd_ilane5[`NIB0]; |
| 264 | rxd_ilane4[`NIB0] <= rxd_ilane5[`NIB1]; |
| 265 | rxd_ilane4[`NIB1] <= rxd_ilane4[`NIB0]; |
| 266 | rxd_ilane3[`NIB0] <= rxd_ilane4[`NIB1]; |
| 267 | rxd_ilane3[`NIB1] <= rxd_ilane3[`NIB0]; |
| 268 | rxd_ilane2[`NIB0] <= rxd_ilane3[`NIB1]; |
| 269 | rxd_ilane2[`NIB1] <= rxd_ilane2[`NIB0]; |
| 270 | rxd_ilane1[`NIB0] <= rxd_ilane2[`NIB1]; |
| 271 | rxd_ilane1[`NIB1] <= rxd_ilane1[`NIB0]; |
| 272 | rxd_ilane0[`NIB0] <= rxd_ilane1[`NIB1]; |
| 273 | rxd_ilane0[`NIB1] <= rxd_ilane0[`NIB0]; |
| 274 | rxd_ilaneX[`NIB] <= rxd_ilane0[`NIB1]; |
| 275 | end |
| 276 | |
| 277 | // rx_dv serial shifter |
| 278 | always @ (posedge rx_nbclk) |
| 279 | if (gmii_mode) |
| 280 | begin |
| 281 | rx_dv_ilane7 <= mg_rx_dv_mux; |
| 282 | rx_dv_ilane6 <= rx_dv_ilane7; |
| 283 | rx_dv_ilane5 <= rx_dv_ilane6; |
| 284 | rx_dv_ilane4 <= rx_dv_ilane5; |
| 285 | rx_dv_ilane3 <= rx_dv_ilane4; |
| 286 | rx_dv_ilane2 <= rx_dv_ilane3; |
| 287 | rx_dv_ilane1 <= rx_dv_ilane2; |
| 288 | rx_dv_ilane0 <= rx_dv_ilane1; |
| 289 | // |
| 290 | rx_dv_ilane7a <= 0; |
| 291 | rx_dv_ilane6a <= 0; |
| 292 | rx_dv_ilane5a <= 0; |
| 293 | rx_dv_ilane4a <= 0; |
| 294 | rx_dv_ilane3a <= 0; |
| 295 | rx_dv_ilane2a <= 0; |
| 296 | rx_dv_ilane1a <= 0; |
| 297 | rx_dv_ilane0a <= 0; |
| 298 | rx_dv_ilaneX <= 0; // laneX |
| 299 | end |
| 300 | else // mii_mode; 10/100Mhz mode |
| 301 | begin |
| 302 | rx_dv_ilane7a <= mg_rx_dv_mux ; |
| 303 | rx_dv_ilane7 <= rx_dv_ilane7a; |
| 304 | rx_dv_ilane6a <= rx_dv_ilane7 ; |
| 305 | rx_dv_ilane6 <= rx_dv_ilane6a; |
| 306 | rx_dv_ilane5a <= rx_dv_ilane6 ; |
| 307 | rx_dv_ilane5 <= rx_dv_ilane5a; |
| 308 | rx_dv_ilane4a <= rx_dv_ilane5 ; |
| 309 | rx_dv_ilane4 <= rx_dv_ilane4a; |
| 310 | rx_dv_ilane3a <= rx_dv_ilane4 ; |
| 311 | rx_dv_ilane3 <= rx_dv_ilane3a; |
| 312 | rx_dv_ilane2a <= rx_dv_ilane3 ; |
| 313 | rx_dv_ilane2 <= rx_dv_ilane2a; |
| 314 | rx_dv_ilane1a <= rx_dv_ilane2 ; |
| 315 | rx_dv_ilane1 <= rx_dv_ilane1a; |
| 316 | rx_dv_ilane0a <= rx_dv_ilane1 ; |
| 317 | rx_dv_ilane0 <= rx_dv_ilane0a; |
| 318 | rx_dv_ilaneX <= rx_dv_ilane0 ; // laneX |
| 319 | end |
| 320 | |
| 321 | // rx_err serial shifter |
| 322 | always @ (posedge rx_nbclk) |
| 323 | if (gmii_mode) |
| 324 | begin // gmii_mode |
| 325 | rx_err_ilane7 <= mg_rx_err_mux; |
| 326 | rx_err_ilane6 <= rx_err_ilane7; |
| 327 | rx_err_ilane5 <= rx_err_ilane6; |
| 328 | rx_err_ilane4 <= rx_err_ilane5; |
| 329 | rx_err_ilane3 <= rx_err_ilane4; |
| 330 | rx_err_ilane2 <= rx_err_ilane3; |
| 331 | rx_err_ilane1 <= rx_err_ilane2; |
| 332 | rx_err_ilane0 <= rx_err_ilane1; |
| 333 | // |
| 334 | rx_err_ilane7a <= 0; |
| 335 | rx_err_ilane6a <= 0; |
| 336 | rx_err_ilane5a <= 0; |
| 337 | rx_err_ilane4a <= 0; |
| 338 | rx_err_ilane3a <= 0; |
| 339 | rx_err_ilane2a <= 0; |
| 340 | rx_err_ilane1a <= 0; |
| 341 | rx_err_ilane0a <= 0; |
| 342 | end |
| 343 | else |
| 344 | begin // mii_mode |
| 345 | rx_err_ilane7a <= mg_rx_err_mux ; |
| 346 | rx_err_ilane7 <= rx_err_ilane7a; |
| 347 | rx_err_ilane6a <= rx_err_ilane7 ; |
| 348 | rx_err_ilane6 <= rx_err_ilane6a; |
| 349 | rx_err_ilane5a <= rx_err_ilane6 ; |
| 350 | rx_err_ilane5 <= rx_err_ilane5a; |
| 351 | rx_err_ilane4a <= rx_err_ilane5 ; |
| 352 | rx_err_ilane4 <= rx_err_ilane4a; |
| 353 | rx_err_ilane3a <= rx_err_ilane4 ; |
| 354 | rx_err_ilane3 <= rx_err_ilane3a; |
| 355 | rx_err_ilane2a <= rx_err_ilane3 ; |
| 356 | rx_err_ilane2 <= rx_err_ilane2a; |
| 357 | rx_err_ilane1a <= rx_err_ilane2 ; |
| 358 | rx_err_ilane1 <= rx_err_ilane1a; |
| 359 | rx_err_ilane0a <= rx_err_ilane1 ; |
| 360 | rx_err_ilane0 <= rx_err_ilane0a; |
| 361 | end |
| 362 | |
| 363 | /* --- end of 1st stage: serial to paralle shifter --------------- */ |
| 364 | |
| 365 | wire [63:0] parallel_rxd = gmii_mode ? |
| 366 | ( |
| 367 | load_ok_state ? |
| 368 | {rxd_ilane7, |
| 369 | rxd_ilane6, |
| 370 | rxd_ilane5, |
| 371 | rxd_ilane4, |
| 372 | rxd_ilane3, |
| 373 | rxd_ilane2, |
| 374 | rxd_ilane1, |
| 375 | rxd_ilane0} : 0 |
| 376 | ) : |
| 377 | ( |
| 378 | load_ok_state ? |
| 379 | {rxd_ilane7[`NIB0], // nibble swap |
| 380 | rxd_ilane7[`NIB1], // nibble swap |
| 381 | rxd_ilane6[`NIB0], // nibble swap |
| 382 | rxd_ilane6[`NIB1], // nibble swap |
| 383 | rxd_ilane5[`NIB0], // nibble swap |
| 384 | rxd_ilane5[`NIB1], // nibble swap |
| 385 | rxd_ilane4[`NIB0], // nibble swap |
| 386 | rxd_ilane4[`NIB1], // nibble swap |
| 387 | rxd_ilane3[`NIB0], // nibble swap |
| 388 | rxd_ilane3[`NIB1], // nibble swap |
| 389 | rxd_ilane2[`NIB0], // nibble swap |
| 390 | rxd_ilane2[`NIB1], // nibble swap |
| 391 | rxd_ilane1[`NIB0], // nibble swap |
| 392 | rxd_ilane1[`NIB1], // nibble swap |
| 393 | rxd_ilane0[`NIB0], // nibble swap |
| 394 | rxd_ilane0[`NIB1]} : 0 |
| 395 | ); |
| 396 | |
| 397 | wire [`BYTE] parallel_rx_dv = load_ok_state ? |
| 398 | {rx_dv_ilane7, |
| 399 | rx_dv_ilane6, |
| 400 | rx_dv_ilane5, |
| 401 | rx_dv_ilane4, |
| 402 | rx_dv_ilane3, |
| 403 | rx_dv_ilane2, |
| 404 | rx_dv_ilane1, |
| 405 | rx_dv_ilane0} : 0; |
| 406 | |
| 407 | wire parallel_rx_err = load_ok_state ? |
| 408 | (rx_err_ilane7 | |
| 409 | rx_err_ilane6 | |
| 410 | rx_err_ilane5 | |
| 411 | rx_err_ilane4 | |
| 412 | rx_err_ilane3 | |
| 413 | rx_err_ilane2 | |
| 414 | rx_err_ilane1 | |
| 415 | rx_err_ilane0 ) : 0; |
| 416 | |
| 417 | wire inc_align_err_count_nbclk = load_ok_state & rx_heart_beat & mii_mode ? |
| 418 | ((rx_dv_ilane7 != rx_dv_ilane7a) | |
| 419 | (rx_dv_ilane6 != rx_dv_ilane6a) | |
| 420 | (rx_dv_ilane5 != rx_dv_ilane5a) | |
| 421 | (rx_dv_ilane4 != rx_dv_ilane4a) | |
| 422 | (rx_dv_ilane3 != rx_dv_ilane3a) | |
| 423 | (rx_dv_ilane2 != rx_dv_ilane2a) | |
| 424 | (rx_dv_ilane1 != rx_dv_ilane1a) | |
| 425 | (rx_dv_ilane0 != rx_dv_ilane0a) ) : 0; |
| 426 | |
| 427 | /* ---------- 2nd stage to hold the data: change clock domain --- */ |
| 428 | wire [63:0] hold_rxd; |
| 429 | wire [7:0] hold_rx_dv; |
| 430 | wire hold_rx_err; |
| 431 | |
| 432 | xREG3 #(64) hold_rxd_xREG3(.din(parallel_rxd[63:0]), |
| 433 | .clk(rx_nbclk), |
| 434 | .en(rx_heart_beat), |
| 435 | .reset(rx_reset_nbclk), |
| 436 | .rst(rxfifo_full_nbclk), |
| 437 | .qout(hold_rxd[63:0])); |
| 438 | |
| 439 | xREG3 #(8) hold_rx_dv_xREG3(.din(parallel_rx_dv), |
| 440 | .clk(rx_nbclk), |
| 441 | .en(rx_heart_beat), |
| 442 | .reset(rx_reset_nbclk), |
| 443 | .rst(rxfifo_full_nbclk), |
| 444 | .qout(hold_rx_dv[7:0])); |
| 445 | |
| 446 | xREG3 #(1) hold_rx_err_xREG3(.din(parallel_rx_err), |
| 447 | .clk(rx_nbclk), |
| 448 | .en(rx_heart_beat), |
| 449 | .reset(rx_reset_nbclk), |
| 450 | .rst(rxfifo_full_nbclk), |
| 451 | .qout(hold_rx_err)); |
| 452 | |
| 453 | |
| 454 | /* ---------- control logic ------------------------------------- */ |
| 455 | |
| 456 | // sfd detection: maybe a pulse assign |
| 457 | // load_ok_state = (grlm_state == PAYLOAD) |
| 458 | |
| 459 | assign rx_det_sfd = gmii_mode ? // a pulse |
| 460 | ((rxd_ilane0[`BYTE0] == `SFD_GMII) & // SFD_GMII == 'hD5 |
| 461 | sfd_win) : // mii_mode |
| 462 | (({rxd_ilaneX[`NIB],rxd_ilane0[`NIB1]} == `SFD_MII) & // SFD_MII == 'h5D |
| 463 | sfd_win) ; // grlm_state NOT in PAYLOAD state |
| 464 | |
| 465 | // eop detection: it is a level |
| 466 | |
| 467 | assign rx_det_eop_lv = ~(rx_dv_ilane0 & |
| 468 | rx_dv_ilane1 & |
| 469 | rx_dv_ilane2 & |
| 470 | rx_dv_ilane3 & |
| 471 | rx_dv_ilane4 & |
| 472 | rx_dv_ilane5 & |
| 473 | rx_dv_ilane6 & |
| 474 | rx_dv_ilane7); |
| 475 | |
| 476 | |
| 477 | //PlsGen rx_det_eop_lead_PlsGen(.reset(rx_reset_nbclk), |
| 478 | // .clk(rx_nbclk), |
| 479 | // .iSigIn(rx_det_eop_lv), |
| 480 | // .oPlsOut(rx_det_eop_lead)); |
| 481 | |
| 482 | |
| 483 | /* --------------- rx_heart_beat timer -------------------- */ |
| 484 | FD1 d_hw_reset_rxnbclk_FD1(.D(hw_reset_rxnbclk), |
| 485 | .CP(rx_nbclk), |
| 486 | .Q(d_hw_reset_rxnbclk)); |
| 487 | |
| 488 | assign hw_reset_rxnbclk_lead = hw_reset_rxnbclk & ~d_hw_reset_rxnbclk; |
| 489 | |
| 490 | reg [3:0] rx_heart_beat_timer; |
| 491 | |
| 492 | always @ (posedge rx_nbclk) |
| 493 | if (hw_reset_rxnbclk_lead) |
| 494 | rx_heart_beat_timer <= 0; |
| 495 | else if (adjust_rx_heart_beat | (~mii_or_gmii_mode)) |
| 496 | rx_heart_beat_timer <= 0; |
| 497 | else rx_heart_beat_timer <= rx_heart_beat_timer + 1; |
| 498 | |
| 499 | reg [3:0] rx_heart_beat_timer_reg; |
| 500 | always @ (posedge rx_nbclk) |
| 501 | rx_heart_beat_timer_reg <= rx_heart_beat_timer; |
| 502 | |
| 503 | |
| 504 | assign rx_heart_beat = mii_mode ? |
| 505 | (rx_heart_beat_timer[3:0] == 4'b0) : |
| 506 | (rx_heart_beat_timer[2:0] == 3'b0) ;// load time |
| 507 | |
| 508 | |
| 509 | /* --------------- instantiation -------------------------- */ |
| 510 | mgrlm_sm mgrlm_sm( |
| 511 | .rx_nbclk(rx_nbclk), |
| 512 | .rx_reset_nbclk(rx_reset_nbclk), |
| 513 | .rx_enable_nbclk(rx_enable_nbclk), |
| 514 | .rx_det_sfd(rx_det_sfd), // ipg_done and rx_det_S are level signals. |
| 515 | .rx_det_eop_lv(rx_det_eop_lv), // rx_det_sfd is level signals. |
| 516 | .rx_heart_beat(rx_heart_beat), |
| 517 | .rxfifo_full_nbclk(rxfifo_full_nbclk), |
| 518 | // outputs |
| 519 | .load_ok_state(load_ok_state), |
| 520 | .adjust_rx_heart_beat(adjust_rx_heart_beat), // should be a pulse |
| 521 | .mgrlm_state(mgrlm_state) |
| 522 | ); |
| 523 | |
| 524 | endmodule // rx_mii_gmii |