Commit | Line | Data |
---|---|---|
86530b38 AT |
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 |