| 1 | // ========== Copyright Header Begin ========================================== |
| 2 | // |
| 3 | // OpenSPARC T2 Processor File: idle_lfsr.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 | `ifdef FBDIMM_FAST_IDLE |
| 36 | |
| 37 | module idle_lfsr(reset, |
| 38 | pn0_out, |
| 39 | pn1_out, |
| 40 | pn2_out, |
| 41 | pn3_out, |
| 42 | pn4_out, |
| 43 | pn5_out, |
| 44 | pn6_out, |
| 45 | pn7_out, |
| 46 | pn8_out, |
| 47 | pn9_out, |
| 48 | pn10_out, |
| 49 | pn11_out, |
| 50 | frm_begin, |
| 51 | frm_boundary, |
| 52 | drc, |
| 53 | clk); |
| 54 | // interface signals |
| 55 | input reset; |
| 56 | input clk; |
| 57 | input frm_begin,frm_boundary; |
| 58 | input [31:0] drc; |
| 59 | output [13:0] pn0_out,pn1_out,pn2_out,pn3_out,pn4_out,pn5_out; |
| 60 | output [13:0] pn11_out,pn10_out,pn9_out,pn8_out,pn7_out,pn6_out; |
| 61 | |
| 62 | |
| 63 | // internal registers/wires |
| 64 | reg [13:0] lfsr_reg; |
| 65 | reg [11:0] Xo; |
| 66 | reg [13:0] Xo_tmp_prev; |
| 67 | reg [13:0] Xo_tmp; |
| 68 | reg [3:0] curr_state; |
| 69 | reg [4:0] reset_cnt; |
| 70 | reg X12,X13; |
| 71 | reg next_idle_state; |
| 72 | reg start_lfsr; |
| 73 | |
| 74 | wire reset_ff; |
| 75 | wire Xo_tmp12; |
| 76 | wire start_lfsr_d; |
| 77 | wire lfsr_clk; |
| 78 | |
| 79 | //assignments |
| 80 | |
| 81 | assign lfsr_clk = next_idle_state; |
| 82 | assign reset_ff=(reset_cnt != 0); |
| 83 | |
| 84 | // Initialization |
| 85 | |
| 86 | // Initialization |
| 87 | initial begin |
| 88 | curr_state = 0; |
| 89 | Xo_tmp = 12'b000000000001; |
| 90 | Xo = 12'b1; |
| 91 | next_idle_state = 1; |
| 92 | reset_cnt = 5'hf; |
| 93 | start_lfsr = 0; |
| 94 | end |
| 95 | |
| 96 | |
| 97 | always@(posedge reset) |
| 98 | start_lfsr<=1; |
| 99 | |
| 100 | assign Xo_tmp12 = next_idle_state ? Xo_tmp[0] : ~Xo_tmp[0]; |
| 101 | assign pn0_out = (start_lfsr & ~reset_ff) ? {Xo_tmp[0],Xo_tmp12,Xo_tmp[11:0]} : 1'b0 ; |
| 102 | assign pn1_out = (start_lfsr & ~reset_ff) ? {Xo_tmp[0],Xo_tmp12,Xo_tmp[11:0]} : 1'b0 ; |
| 103 | assign pn2_out = (start_lfsr & ~reset_ff) ? {Xo_tmp[0],Xo_tmp12,Xo_tmp[11:0]} : 1'b0 ; |
| 104 | assign pn3_out = (start_lfsr & ~reset_ff) ? {Xo_tmp[0],Xo_tmp12,Xo_tmp[11:0]} : 1'b0 ; |
| 105 | assign pn4_out = (start_lfsr & ~reset_ff) ? {Xo_tmp[0],Xo_tmp12,Xo_tmp[11:0]} : 1'b0 ; |
| 106 | assign pn5_out = (start_lfsr & ~reset_ff) ? {Xo_tmp[0],Xo_tmp12,Xo_tmp[11:0]} : 1'b0 ; |
| 107 | assign pn6_out = (start_lfsr & ~reset_ff) ? {Xo_tmp[0],~Xo_tmp12,Xo_tmp[11:0]} : 1'b0 ; |
| 108 | assign pn7_out = (start_lfsr & ~reset_ff) ? {Xo_tmp[0],~Xo_tmp12,Xo_tmp[11:0]} : 1'b0 ; |
| 109 | assign pn8_out = (start_lfsr & ~reset_ff) ? {Xo_tmp[0],~Xo_tmp12,Xo_tmp[11:0]} : 1'b0 ; |
| 110 | assign pn9_out = (start_lfsr & ~reset_ff) ? {Xo_tmp[0],~Xo_tmp12,Xo_tmp[11:0]} : 1'b0 ; |
| 111 | assign pn10_out = (start_lfsr & ~reset_ff) ? {Xo_tmp[0],~Xo_tmp12,Xo_tmp[11:0]} : 1'b0 ; |
| 112 | assign pn11_out = (start_lfsr & ~reset_ff) ? {Xo_tmp[0],~Xo_tmp12,Xo_tmp[11:0]} : 1'b0 ; |
| 113 | |
| 114 | shifter_p #(1) shft_start_lfsr (.signal_in (start_lfsr), |
| 115 | .signal_out (start_lfsr_d), |
| 116 | .delay_cycles ( 5 ), |
| 117 | .clk (clk)); |
| 118 | |
| 119 | always@(posedge frm_boundary) if ( start_lfsr ) |
| 120 | begin |
| 121 | if (reset_cnt) |
| 122 | reset_cnt<=reset_cnt-1; |
| 123 | end else begin |
| 124 | reset_cnt <= 9 + drc[7:4] + drc[3:0]; |
| 125 | end |
| 126 | |
| 127 | |
| 128 | always @(posedge frm_boundary) if ( start_lfsr ) |
| 129 | begin |
| 130 | if (reset_ff) begin |
| 131 | Xo <= 12'b1; |
| 132 | Xo_tmp <= 12'b1; |
| 133 | end |
| 134 | else begin |
| 135 | |
| 136 | Xo[11] <= Xo[0] ^ Xo[3] ^ Xo[4] ^ Xo[7]; |
| 137 | Xo[10] <= Xo[11]; |
| 138 | Xo[9] <= Xo[10]; |
| 139 | Xo[8] <= Xo[9]; |
| 140 | Xo[7] <= Xo[8]; |
| 141 | Xo[6] <= Xo[7]; |
| 142 | Xo[5] <= Xo[6]; |
| 143 | Xo[4] <= Xo[5]; |
| 144 | Xo[3] <= Xo[4]; |
| 145 | Xo[2] <= Xo[3]; |
| 146 | Xo[1] <= Xo[2]; |
| 147 | Xo[0] <= Xo[1]; |
| 148 | |
| 149 | Xo_tmp[11] <= Xo_tmp[0] ^ Xo_tmp[3] ^ Xo_tmp[4] ^ Xo_tmp[7]; |
| 150 | Xo_tmp[10] <= Xo_tmp[11]; |
| 151 | Xo_tmp[9] <= Xo_tmp[10]; |
| 152 | Xo_tmp[8] <= Xo_tmp[9]; |
| 153 | Xo_tmp[7] <= Xo_tmp[8]; |
| 154 | Xo_tmp[6] <= Xo_tmp[7]; |
| 155 | Xo_tmp[5] <= Xo_tmp[6]; |
| 156 | Xo_tmp[4] <= Xo_tmp[5]; |
| 157 | Xo_tmp[3] <= Xo_tmp[4]; |
| 158 | Xo_tmp[2] <= Xo_tmp[3]; |
| 159 | Xo_tmp[1] <= Xo_tmp[2]; |
| 160 | Xo_tmp[0] <= Xo_tmp[1]; |
| 161 | |
| 162 | end |
| 163 | end |
| 164 | |
| 165 | |
| 166 | |
| 167 | endmodule |
| 168 | |
| 169 | |
| 170 | `else |
| 171 | |
| 172 | module idle_lfsr (reset, frm_begin, dtm_reset, lfsr_output, clk, frm_boundary, electrical_idle); |
| 173 | // interface signals |
| 174 | input reset; |
| 175 | input clk; |
| 176 | input frm_boundary; |
| 177 | input frm_begin; |
| 178 | input electrical_idle; |
| 179 | input dtm_reset; |
| 180 | output [13:0] lfsr_output; |
| 181 | |
| 182 | |
| 183 | // internal registers/wires |
| 184 | reg [13:0] lfsr_reg; |
| 185 | reg [11:0] Xo; |
| 186 | reg [13:0] Xo_tmp; |
| 187 | reg [3:0] curr_state; |
| 188 | reg X12,X13; |
| 189 | reg next_idle_state; |
| 190 | reg start_lfsr; |
| 191 | reg [3:0] reset_cnt; |
| 192 | wire reset_ff=(reset_cnt != 0); |
| 193 | wire Xo_tmp12; |
| 194 | wire lfsr_clk; |
| 195 | |
| 196 | |
| 197 | initial begin |
| 198 | Xo_tmp=0; |
| 199 | start_lfsr=0; |
| 200 | end |
| 201 | |
| 202 | always@(posedge clk) |
| 203 | begin |
| 204 | if ( electrical_idle ) |
| 205 | begin |
| 206 | start_lfsr<=0; |
| 207 | end |
| 208 | |
| 209 | `ifdef DTM_ENABLED |
| 210 | if ( dtm_reset ) |
| 211 | start_lfsr=1; |
| 212 | `else |
| 213 | if ( reset ) |
| 214 | start_lfsr<=1; |
| 215 | `endif |
| 216 | |
| 217 | end |
| 218 | |
| 219 | |
| 220 | assign Xo_tmp12 = next_idle_state ? Xo_tmp[0] : ~Xo_tmp[0]; |
| 221 | |
| 222 | `ifdef DTM_ENABLED |
| 223 | |
| 224 | reg enable_lfsr_output; |
| 225 | |
| 226 | always@(negedge frm_boundary) |
| 227 | begin |
| 228 | if ( start_lfsr & ~reset_ff ) |
| 229 | enable_lfsr_output <= 1'b1; |
| 230 | else |
| 231 | enable_lfsr_output <= 1'b0; |
| 232 | end |
| 233 | |
| 234 | |
| 235 | assign lfsr_output[13:0]= (enable_lfsr_output) ? {Xo_tmp[0],Xo_tmp12,Xo_tmp[11:0]} : 1'b0 ; |
| 236 | |
| 237 | |
| 238 | `else |
| 239 | assign lfsr_output[13:0]= (start_lfsr & ~reset_ff) ? {Xo_tmp[0],Xo_tmp12,Xo_tmp[11:0]} : 1'b0 ; |
| 240 | `endif |
| 241 | |
| 242 | assign lfsr_clk = next_idle_state; |
| 243 | |
| 244 | always@(posedge frm_boundary) if ( start_lfsr | electrical_idle ) |
| 245 | begin |
| 246 | if (reset_cnt ) |
| 247 | reset_cnt <= reset_cnt - 1; |
| 248 | |
| 249 | if( electrical_idle ) |
| 250 | begin |
| 251 | `ifdef DTM_ENABLED |
| 252 | reset_cnt=4'h1; |
| 253 | `else |
| 254 | reset_cnt<=4'hc; |
| 255 | `endif |
| 256 | end |
| 257 | |
| 258 | |
| 259 | |
| 260 | end |
| 261 | |
| 262 | |
| 263 | always @(posedge lfsr_clk) begin |
| 264 | if ( electrical_idle) |
| 265 | Xo_tmp<=12'b000000000001; |
| 266 | else |
| 267 | Xo_tmp[11:0] <= Xo[11:0]; |
| 268 | |
| 269 | |
| 270 | end |
| 271 | |
| 272 | |
| 273 | |
| 274 | `ifdef FBDIMM_FAST |
| 275 | |
| 276 | reg start_lfsr_d7; |
| 277 | `ifdef DTM_ENABLED |
| 278 | always@(negedge frm_begin) |
| 279 | start_lfsr_d7 <= start_lfsr; |
| 280 | `else |
| 281 | always@(negedge frm_boundary) |
| 282 | start_lfsr_d7 <= start_lfsr; |
| 283 | `endif |
| 284 | |
| 285 | //`endif |
| 286 | |
| 287 | `else |
| 288 | wire start_lfsr_d7; |
| 289 | |
| 290 | shifter_p #(1) shft (.signal_in ( start_lfsr ), |
| 291 | .signal_out (start_lfsr_d7), |
| 292 | .delay_cycles ( 10'h8 ), |
| 293 | .clk (clk)); |
| 294 | `endif |
| 295 | |
| 296 | always@(posedge clk) if ( start_lfsr_d7 | electrical_idle ) |
| 297 | begin |
| 298 | if ( electrical_idle ) |
| 299 | begin |
| 300 | next_idle_state <= 1; |
| 301 | curr_state<=0; |
| 302 | end |
| 303 | else |
| 304 | case(curr_state) |
| 305 | 4'h0: begin curr_state <= 4'h1; end |
| 306 | 4'h1: begin curr_state <= 4'h2; end |
| 307 | 4'h2: begin curr_state <= 4'h3; end |
| 308 | 4'h3: begin curr_state <= 4'h4; end |
| 309 | 4'h4: begin curr_state <= 4'h5; end |
| 310 | 4'h5: begin curr_state <= 4'h6; next_idle_state <= ~next_idle_state; end |
| 311 | 4'h6: begin curr_state <= 4'h7; end |
| 312 | 4'h7: begin curr_state <= 4'h8; end |
| 313 | 4'h8: begin curr_state <= 4'h9; end |
| 314 | 4'h9: begin curr_state <= 4'ha; end |
| 315 | 4'ha: begin curr_state <= 4'hb; end |
| 316 | 4'hb: begin curr_state <= 4'h0; next_idle_state <= ~next_idle_state; end |
| 317 | endcase |
| 318 | end |
| 319 | |
| 320 | |
| 321 | always @(posedge lfsr_clk) begin |
| 322 | if (reset_ff) |
| 323 | Xo <= 12'b1; |
| 324 | else begin |
| 325 | Xo[11] <= Xo[0] ^ Xo[3] ^ Xo[4] ^ Xo[7]; |
| 326 | Xo[10] <= Xo[11]; |
| 327 | Xo[9] <= Xo[10]; |
| 328 | Xo[8] <= Xo[9]; |
| 329 | Xo[7] <= Xo[8]; |
| 330 | Xo[6] <= Xo[7]; |
| 331 | Xo[5] <= Xo[6]; |
| 332 | Xo[4] <= Xo[5]; |
| 333 | Xo[3] <= Xo[4]; |
| 334 | Xo[2] <= Xo[3]; |
| 335 | Xo[1] <= Xo[2]; |
| 336 | Xo[0] <= Xo[1]; |
| 337 | end |
| 338 | end |
| 339 | |
| 340 | |
| 341 | // Initialization |
| 342 | initial begin |
| 343 | curr_state=0; |
| 344 | Xo_tmp=12'b000000000001; |
| 345 | next_idle_state=1; |
| 346 | reset_cnt=4'hc; |
| 347 | end |
| 348 | |
| 349 | endmodule |
| 350 | |
| 351 | |
| 352 | `ifdef AXIS_FBDIMM_HW |
| 353 | `else |
| 354 | module chmon_idle_lfsr(reset, |
| 355 | pn_prev_in, |
| 356 | pn_curr_in, |
| 357 | is_idle, |
| 358 | frm_begin, |
| 359 | alert_frame, |
| 360 | nb_config, |
| 361 | frm_boundary, |
| 362 | clk); |
| 363 | // interface signals |
| 364 | input reset; |
| 365 | input clk; |
| 366 | input is_idle; |
| 367 | input [3:0] nb_config; |
| 368 | input frm_begin,frm_boundary; |
| 369 | input [13:0] pn_prev_in,pn_curr_in; |
| 370 | output alert_frame; |
| 371 | |
| 372 | |
| 373 | // internal registers/wires |
| 374 | reg [13:0] lfsr_reg; |
| 375 | wire [13:0] Xo, pn_prev_in_map,pn_curr_in_map; |
| 376 | wire [11:0] next_Xo; |
| 377 | reg [13:0] Xo_tmp_prev; |
| 378 | reg [3:0] curr_state; |
| 379 | reg X12,X13; |
| 380 | reg next_idle_state; |
| 381 | reg start_lfsr; |
| 382 | reg [4:0] reset_cnt; |
| 383 | wire reset_ff=(reset_cnt != 0); |
| 384 | wire Xo_tmp12; |
| 385 | reg [11:0] Xo_tmp; |
| 386 | wire start_lfsr_d; |
| 387 | reg alert_frame_reg; |
| 388 | |
| 389 | |
| 390 | assign alert_frame = alert_frame_reg; |
| 391 | |
| 392 | assign pn_prev_in_map = (( nb_config == 4'b1111 )) ? pn_prev_in : // All lanes are good |
| 393 | (( nb_config == 4'b1101 )) ? {pn_prev_in[13:0]} : // map nb13 |
| 394 | (( nb_config == 4'b1100 )) ? {pn_prev_in[13] ,pn_prev_in[11:0]} : // map nb12 |
| 395 | (( nb_config == 4'b1011 )) ? {pn_prev_in[13:12],pn_prev_in[10:0]} : // map nb11 |
| 396 | (( nb_config == 4'b1010 )) ? {pn_prev_in[13:11],pn_prev_in[09:0]} : // map nb10 |
| 397 | (( nb_config == 4'b1001 )) ? {pn_prev_in[13:10],pn_prev_in[08:0]} : // map nb9 |
| 398 | (( nb_config == 4'b1000 )) ? {pn_prev_in[13:09],pn_prev_in[07:0]} : // map nb8 |
| 399 | (( nb_config == 4'b0111 )) ? {pn_prev_in[13:08],pn_prev_in[06:0]} : // map nb7 |
| 400 | (( nb_config == 4'b0110 )) ? {pn_prev_in[13:07],pn_prev_in[05:0]} : // map nb6 |
| 401 | (( nb_config == 4'b0101 )) ? {pn_prev_in[13:06],pn_prev_in[04:0]} : // map nb5 |
| 402 | (( nb_config == 4'b0100 )) ? {pn_prev_in[13:05],pn_prev_in[03:0]} : // map nb4 |
| 403 | (( nb_config == 4'b0011 )) ? {pn_prev_in[13:04],pn_prev_in[02:0]} : // map nb3 |
| 404 | (( nb_config == 4'b0010 )) ? {pn_prev_in[13:03],pn_prev_in[01:0]} : // map nb2 |
| 405 | (( nb_config == 4'b0001 )) ? {pn_prev_in[13:02],pn_prev_in[0] } : // map nb1 |
| 406 | (( nb_config == 4'b0000 )) ? {pn_prev_in[13:01]} : pn_prev_in; // map nb0 |
| 407 | |
| 408 | assign pn_curr_in_map = (( nb_config == 4'b1111 )) ? pn_curr_in : // All lanes are good |
| 409 | (( nb_config == 4'b1101 )) ? {pn_curr_in[13:0]} : // map nb13 |
| 410 | (( nb_config == 4'b1100 )) ? {pn_curr_in[13] ,pn_curr_in[11:0]} : // map nb12 |
| 411 | (( nb_config == 4'b1011 )) ? {pn_curr_in[13:12],pn_curr_in[10:0]} : // map nb11 |
| 412 | (( nb_config == 4'b1010 )) ? {pn_curr_in[13:11],pn_curr_in[09:0]} : // map nb10 |
| 413 | (( nb_config == 4'b1001 )) ? {pn_curr_in[13:10],pn_curr_in[08:0]} : // map nb9 |
| 414 | (( nb_config == 4'b1000 )) ? {pn_curr_in[13:09],pn_curr_in[07:0]} : // map nb8 |
| 415 | (( nb_config == 4'b0111 )) ? {pn_curr_in[13:08],pn_curr_in[06:0]} : // map nb7 |
| 416 | (( nb_config == 4'b0110 )) ? {pn_curr_in[13:07],pn_curr_in[05:0]} : // map nb6 |
| 417 | (( nb_config == 4'b0101 )) ? {pn_curr_in[13:06],pn_curr_in[04:0]} : // map nb5 |
| 418 | (( nb_config == 4'b0100 )) ? {pn_curr_in[13:05],pn_curr_in[03:0]} : // map nb4 |
| 419 | (( nb_config == 4'b0011 )) ? {pn_curr_in[13:04],pn_curr_in[02:0]} : // map nb3 |
| 420 | (( nb_config == 4'b0010 )) ? {pn_curr_in[13:03],pn_curr_in[01:0]} : // map nb2 |
| 421 | (( nb_config == 4'b0001 )) ? {pn_curr_in[13:02],pn_curr_in[0] } : // map nb1 |
| 422 | (( nb_config == 4'b0000 )) ? {pn_curr_in[13:01]} : pn_curr_in; // map nb0 |
| 423 | |
| 424 | |
| 425 | always@(negedge frm_boundary) |
| 426 | begin |
| 427 | if (~reset & is_idle ) |
| 428 | begin |
| 429 | if ( ( pn_curr_in_map !== 14'h0 ) && ( pn_prev_in_map !== 14'h0 ) ) |
| 430 | begin |
| 431 | if ( |
| 432 | ( pn_curr_in_map[0] == pn_prev_in_map[01] ) && |
| 433 | ( pn_curr_in_map[1] == pn_prev_in_map[02] ) && |
| 434 | ( pn_curr_in_map[2] == pn_prev_in_map[03] ) && |
| 435 | ( pn_curr_in_map[3] == pn_prev_in_map[04] ) && |
| 436 | ( pn_curr_in_map[4] == pn_prev_in_map[05] ) && |
| 437 | ( pn_curr_in_map[5] == pn_prev_in_map[06] ) && |
| 438 | ( pn_curr_in_map[6] == pn_prev_in_map[07] ) && |
| 439 | ( pn_curr_in_map[7] == pn_prev_in_map[08] ) && |
| 440 | ( pn_curr_in_map[8] == pn_prev_in_map[09] ) && |
| 441 | ( pn_curr_in_map[9] == pn_prev_in_map[10] ) && |
| 442 | ( pn_curr_in_map[10] == pn_prev_in_map[11] ) && |
| 443 | ( pn_curr_in_map[11] == ( pn_prev_in_map[00] ^ pn_prev_in_map[3] ^ pn_prev_in_map[4] ^ pn_prev_in_map[7]) ) ) |
| 444 | // this is an expected idle frame |
| 445 | alert_frame_reg <= 0; |
| 446 | else |
| 447 | alert_frame_reg <= 1; |
| 448 | end // if ( ( pn_curr_in !== 14'h0 ) && ( pn_prev_in !== 14'h0 ) ) |
| 449 | end // (~reset & is_idle ) |
| 450 | else |
| 451 | alert_frame_reg <=0 ; |
| 452 | |
| 453 | end |
| 454 | |
| 455 | endmodule |
| 456 | |
| 457 | `endif |
| 458 | |
| 459 | |
| 460 | |
| 461 | `endif |