Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / model / pcie / pl / ltssm.cpp
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: ltssm.cpp
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#include "systemc.h"
36#include "pl/ltssm.h"
37using namespace Logger;
38
39/********** Commenting Starts **********
40 Samples the input bus signals
41 ********** Commenting Ends **********/
42
43void ltssm::in_block()
44{
45 int i;
46 // Initialize ts1_set_const for first time use
47 while(true)
48 {
49 if(reset_por_l.read())
50 {
51 in_val = lane_in.read();
52 in_val_bar = lane_in_bar.read();
53
54 for(i=0;i<LINK_WIDTH;i++)
55 {
56 ireg_in_p_p[i] = (in_val.range(i,i),ireg_in_p_p[i].range(9,1)); // After 10 clock cycles all having the COM symbol
57 ireg_in_p_p_bar[i] = (in_val_bar.range(i,i),ireg_in_p_p_bar[i].range(9,1));
58 }
59 ireg = in_val;
60 ireg_bar = in_val_bar; // Read in the in_val
61 }
62 else
63 {
64 generated_pattern = 0;
65 }
66 wait(link_clk.posedge_event());
67 }
68}
69
70/// CSR event block 1
71void ltssm::read_csr_block() // Read LNK_CTL_HW CSR to look at disable link/scrambling etc
72{
73 csr_port.set_notify_event(PEU_CSR_A_LNK_CTL_HW_ADDR,&link_sts_csr_ev);
74 while(true)
75 {
76 wait(link_sts_csr_ev);
77 link_ctl_csr = csr_port.read_csr(PEU_CSR_A_LNK_CTL_HW_ADDR);
78 }
79}
80
81/// CSR event block 2
82void ltssm::read_csr1_block() // This CSR read is for HOT-RESET control
83{
84 csr_port.set_notify_event(PEU_CSR_A_LINK_CTL_HW_ADDR,&macl_pcs_ctl_ev);
85 while(true)
86 {
87 wait(macl_pcs_ctl_ev);
88 macl_pcs_ctl_csr = csr_port.read_csr(PEU_CSR_A_LINK_CTL_HW_ADDR);
89 }
90}
91
92/// Output assignment
93void ltssm::assign_block2()
94{
95 while(true)
96 {
97 if(reset_por_l.read())
98 {
99 lane_out.write(out_reg);
100 lane_out_bar.write(out_reg_bar); // Write out the value from the transmitter
101 }
102 if((((init_state == L0) && q_not_empty.read() && (idle_pattern_bit == 0)) || (init_state == L0 && !q_not_empty.read() && idle_pattern_bit == 0 && transmitted_idl_pattern >= 18)) && reset_l.read() && reset_por_l.read())
103 write_init_done = true;
104
105 wait(link_clk.posedge_event());
106 }
107}
108
109/// Receiver port frame boundary
110void ltssm::frame_boundary_assign_rx()
111{
112 while(true)
113 {
114 frame_boundary_reg = frame_boundary_detected ? (lock_counter == sym_counter) : 0; // Receive frame boundary calculation
115 frame_boundary_rx.write(frame_boundary_reg);
116 if((((init_state_rx == L0) && q_not_empty.read() && (idle_pattern_bit == 0)) ||
117 (init_state_rx == L0 && !q_not_empty.read() && (idle_pattern_bit == 0) && transmitted_idl_pattern >= 18)) &&
118 reset_l.read() && reset_por_l.read()) // Move to pl_top if more than 18 idle patterns have been sent and still nothing in the DLL/TL Q
119 write_init_done_rx = true;
120 wait(link_clk.posedge_event());
121 }
122}
123
124/// Transmitter port frame boundary
125void ltssm::frame_boundary_assign()
126{
127 while(true)
128 {
129 if(out_reg_ser.range(9,0) == 0x305 || out_reg_ser.range(9,0) == 0xfa) // Transmit frame boundary calculation
130 {
131 com_detected_tx = true;
132 }
133 if(com_detected_tx)
134 start_frame_boundary_tx = true;
135 if(start_frame_boundary_tx)
136 {
137 frame_boundary_tx_counter++;
138 frame_boundary_tx_counter %= 10;
139 frame_boundary_reg_tx = (frame_boundary_tx_counter == 0) ? 1 : 0;
140 }
141 else
142 {
143 frame_boundary_reg_tx = !(frame_boundary_reg_tx);
144 }
145 frame_boundary_tx.write(frame_boundary_reg_tx);
146 wait(link_clk.posedge_event());
147 }
148}
149
150/// Receiver port frame boundary counter
151void ltssm::counter_block0() // Counter block for receive side
152{
153 int prev_lock_counter;
154 while(true)
155 {
156 if(sym_counter == 10)
157 sym_counter = 1;
158 else
159 sym_counter = sym_counter + 1;
160
161 prev_lock_counter = lock_counter;
162 if(com_detected) // This is calculated in the posedge block so should not be a race
163 lock_counter = (sym_counter < 4) ? (sym_counter == 1) ? 8 : (sym_counter == 2)? 9 : 10 : sym_counter - 3;
164
165 wait(link_clk.negedge_event());
166 }
167}
168
169/// Receiver side frame boundary counter block
170void ltssm::counter_block2() // Counter block for receive side to check for COM_DETECTED
171{
172 int i,com_counter;
173 while(true)
174 {
175 com_counter = 0;
176 for(i=0;i<LINK_WIDTH;i++)
177 {
178 if(((ireg_in[i].range(9,0) == COM_10b) || (ireg_in_bar[i].range(9,0) == COM_10b)))
179 {
180 com_counter++;
181 }
182 }
183 if(com_counter == LINK_WIDTH)
184 {
185 com_detected = 1;
186 frame_boundary_detected = 1;
187 }
188 else
189 com_detected = 0;
190
191 for(i=0;i<LINK_WIDTH;i++)
192 {
193 ireg_in_p[i] = ireg_in[i];
194 ireg_in_p_bar[i] = ireg_in_bar[i];
195 }
196 wait(link_clk.posedge_event());
197 }
198}
199
200/// One more read block
201void ltssm::counter_block4() // Staged negedge_clk in data read
202{
203 int i;
204 while(true)
205 {
206 if(reset_por_l.read())
207 {
208 for(i=0; i< LINK_WIDTH; i++)
209 {
210 ireg_in[i] = (in_val.range(i,i),ireg_in[i].range(9,1)); // After 10 clock cycles all having the COM symbol
211 ireg_in_bar[i] = (in_val_bar.range(i,i),ireg_in_bar[i].range(9,1));
212 }
213 }
214 else
215 {
216 for(i=0;i< LINK_WIDTH; i++)
217 {
218 ireg_in[i] = 0;
219 ireg_in_bar[i] = 1;
220 }
221 }
222 wait(link_clk.negedge_event());
223 }
224}
225
226/// Block to check and process received/sampled data
227void ltssm::rx_block() // Main block to receive data based on current LTSSM state
228{
229 int i,diff_lane_num_ok = 0,lane_num_ok=0,j,k;
230 map<int,int>::iterator iter,iter1,iter2,iter3;
231 map<int,int>::iterator iter_n,iter1_n,iter2_n,iter3_n;
232 map<int,int>::iterator iter_0,iter_1,iter_2,iter_3,iter_4,iter_5,iter_6,iter_7,iter_8,iter_9;
233 map<int,int>::iterator iter_0_n,iter_1_n,iter_2_n,iter_3_n,iter_4_n,iter_5_n,iter_6_n,iter_7_n,iter_8_n,iter_9_n;
234 unsigned short tmp_lfsr;
235 sc_lv<10> scramble_pattern = 0x000;
236 for(i=0;i<256;i++)
237 {
238 map_iter = map_table->data_encode_map.find(i);
239 encoded_value[i] = map_iter->second;
240 map_iter = map_table->neg_data_encode_map.find(i);
241 neg_encoded_value[i] = map_iter->second;
242 }
243
244 while(true)
245 {
246 if(reset_por_l.read()) // System has come out of reset
247 {
248 // Check for the symbol and store it as is
249 // Check to see if ireg_in_p[0] -> decoder -> descrambler = 0x00 once LTSSM reaches CFG_IDLE
250 // If no, reset back the descrambler lfsr to 0xffff
251 // If yes, start the descrambler and the scrambler after receiving 1 Logical Idle frame
252
253 if(com_detected)
254 {
255 ts1_2 = 0x0000000000000000000000000000000000000000; // Wipe out the ts1_2 set and start a new pattern
256 ts1_2 = (ireg_in_p_p[0],ts1_2.range(159,10)); // We can safely assume that TS1/TS2/IDLE/FTS/SKIP ordered set has started
257 ts1_2_negedge = (ireg_in_p[0],ts1_2_negedge.range(159,10)); // We can safely assume that TS1/TS2/IDLE/FTS/SKIP ordered set has started
258 fts_set = (ireg_in_p_p[0],fts_set.range(39,10));
259 fts_set_negedge = (ireg_in_p[0],fts_set_negedge.range(39,10));
260 skip_set = (ireg_in_p_p[0],skip_set.range(39,10));
261 skip_set_negedge = (ireg_in_p[0],skip_set_negedge.range(39,10));
262 electrical_idle_set = (ireg_in_p_p[0],electrical_idle_set.range(39,10));
263 electrical_idle_set_negedge = (ireg_in_p[0],electrical_idle_set_negedge.range(39,10));
264 for(i=0;i<LINK_WIDTH;i++)
265 {
266 ts1_2_serial[i] = (ireg_in_p_p[i],ts1_2_serial[i].range(159,10));
267 ts1_2_serial_negedge[i] = (ireg_in_p[i],ts1_2_serial_negedge[i].range(159,10));
268 }
269 start_ordered_set = 1;
270 negedge_skip_this = true;
271 if(!init_done_rx.read())
272 {
273 descrambler_i->scramble_descramble_all(K28_5,0,1); // This should reset the LFSR
274 }
275 }
276 electrical_idle_constant_voltage_set = (ireg_in_p_p[0],electrical_idle_constant_voltage_set.range(9,1));
277 if(frame_boundary_reg.read() || come_next_time)
278 {
279 if(frame_boundary_reg.read())
280 come_next_time = 1;
281 else
282 come_next_time = 0;
283 if(!come_next_time && ((init_state == CFG_IDLE) || (init_state == Recovery_Idle)) && !init_done_rx.read()) // The data I have right now will use the previous LFSR
284 {
285 iter = map_table->data_decode_map.find(ireg_in_p_p[0].range(0,9).to_uint());
286 iter1 = map_table->neg_data_decode_map.find(ireg_in_p_p[0].range(0,9).to_uint()); // Say we get 0x8d (just for example)
287 iter2 = map_table->spec_symbol_decode_map.find(ireg_in_p_p[0].range(0,9).to_uint());
288 iter3 = map_table->neg_spec_symbol_decode_map.find(ireg_in_p_p[0].range(0,9).to_uint());
289 iter_n = map_table->data_decode_map.find(ireg_in_p[0].range(0,9).to_uint()); // For Data changing at negedge clock
290 iter1_n = map_table->neg_data_decode_map.find(ireg_in_p[0].range(0,9).to_uint()); // For data changing at negedge clock
291 iter2_n = map_table->spec_symbol_decode_map.find(ireg_in_p[0].range(0,9).to_uint());
292 iter3_n = map_table->neg_spec_symbol_decode_map.find(ireg_in_p[0].range(0,9).to_uint());
293 // Get the lfsr in sync with the EP lfsr
294
295 /// Section when data changes at the posedge of clock. Check for DISPARITY error checks
296 if(!lock_negedge_clock)
297 {
298 for(i=0;i<LINK_WIDTH;i++)
299 {
300 iter_0 = map_table->spec_symbol_decode_map.find(ireg_in_p_p[i].range(0,9).to_uint()); // Iterator for (+) spec symbol map table
301 iter_1 = map_table->neg_spec_symbol_decode_map.find(ireg_in_p_p[i].range(0,9).to_uint()); // Iterator for (-) spec symbol map table
302 iter_2 = map_table->data_decode_map.find(ireg_in_p_p[i].range(0,9).to_uint()); // Iterator for (+) data symbol map table
303 iter_3 = map_table->neg_data_decode_map.find(ireg_in_p_p[i].range(0,9).to_uint()); // Iterator for (-) data symbol map table
304 if(iter_0 != map_table->spec_symbol_decode_map.end())
305 {
306 if(!curr_running_disp->get_rx_CRD(i).to_bool())
307 LOG_WARNING << "WARNING : _LTSSM_ : Positive Running Disparity Error in lane " << i;
308 else // Set the disparity according to the symbol received
309 {
310 if(curr_running_disp->calculate_disparity(ireg_in_p_p[i].range(0,9),0) == 1)
311 curr_running_disp->set_rx_CRD(i,sc_logic(1));
312 else if(curr_running_disp->calculate_disparity(ireg_in_p_p[i].range(0,9),0) == 0)
313 curr_running_disp->set_rx_CRD(i,sc_logic(0));
314 }
315 }
316 else if(iter_1 != map_table->neg_spec_symbol_decode_map.end())
317 {
318 if(curr_running_disp->get_rx_CRD(i).to_bool())
319 LOG_WARNING << "WARNING : _LTSSM_ : Negative Running Disparity Error in lane " << i;
320 else // Set the disparity according to the symbol received
321 {
322 if(curr_running_disp->calculate_disparity(ireg_in_p_p[i].range(0,9),0) == 1)
323 curr_running_disp->set_rx_CRD(i,sc_logic(1));
324 else if(curr_running_disp->calculate_disparity(ireg_in_p_p[i].range(0,9),0) == 0)
325 curr_running_disp->set_rx_CRD(i,sc_logic(0));
326 }
327 }
328 else if(iter_2 != map_table->data_decode_map.end())
329 {
330 if(!curr_running_disp->get_rx_CRD(i).to_bool() && curr_running_disp->calculate_disparity(ireg_in_p_p[i].range(0,9),0) != 2)
331 LOG_WARNING << "WARNING : _LTSSM_ : Positive Running Disparity Error in lane " << i;
332 else // Set the disparity according to the symbol received
333 {
334 if(curr_running_disp->calculate_disparity(ireg_in_p_p[i].range(0,9),0) == 1)
335 curr_running_disp->set_rx_CRD(i,sc_logic(1));
336 else if(curr_running_disp->calculate_disparity(ireg_in_p_p[i].range(0,9),0) == 0)
337 curr_running_disp->set_rx_CRD(i,sc_logic(0));
338 }
339 }
340 else if(iter_3 != map_table->neg_data_decode_map.end() && curr_running_disp->calculate_disparity(ireg_in_p_p[i].range(0,9),0) != 2)
341 {
342 if(curr_running_disp->get_rx_CRD(i).to_bool())
343 LOG_WARNING << "WARNING : _LTSSM_ : Negative Running Disparity Error in lane " << i;
344 else // Set the disparity according to the symbol received
345 {
346 if(curr_running_disp->calculate_disparity(ireg_in_p_p[i].range(0,9),0) == 1)
347 curr_running_disp->set_rx_CRD(i,sc_logic(1));
348 else if(curr_running_disp->calculate_disparity(ireg_in_p_p[i].range(0,9),0) == 0)
349 curr_running_disp->set_rx_CRD(i,sc_logic(0));
350 }
351 }
352 }
353 if(iter2 != map_table->spec_symbol_decode_map.end()) // All lanes should have the IDLE packet
354 idle_set[0] = iter2->second;
355 else if(iter3 != map_table->neg_spec_symbol_decode_map.end())
356 idle_set[0] = iter3->second;
357 else if(iter != map_table->data_decode_map.end())
358 idle_set[0] = iter->second;
359 else if(iter1 != map_table->neg_data_decode_map.end())
360 idle_set[0] = iter1->second;
361 }
362 /// Disparity checks for data changing at the negedge clock
363 else
364 {
365 for(i=0;i<10;i++)
366 {
367 iter_0 = map_table->spec_symbol_decode_map.find(ireg_in_p[i].range(0,9).to_uint());
368 iter_1 = map_table->neg_spec_symbol_decode_map.find(ireg_in_p[i].range(0,9).to_uint());
369 iter_2 = map_table->data_decode_map.find(ireg_in_p[i].range(0,9).to_uint());
370 iter_3 = map_table->neg_data_decode_map.find(ireg_in_p[i].range(0,9).to_uint());
371 if(iter_0 != map_table->spec_symbol_decode_map.end())
372 {
373 if(!curr_running_disp->get_rx_CRD(i).to_bool())
374 LOG_WARNING << "WARNING : _LTSSM_ : Positive Running Disparity Error in lane " << i;
375 else // Set the disparity according to the symbol received
376 {
377 if(curr_running_disp->calculate_disparity(ireg_in_p[i].range(0,9),0) == 1)
378 curr_running_disp->set_rx_CRD(i,sc_logic(1));
379 else if(curr_running_disp->calculate_disparity(ireg_in_p[i].range(0,9),0) == 0)
380 curr_running_disp->set_rx_CRD(i,sc_logic(0));
381 }
382 }
383 else if(iter_1 != map_table->neg_spec_symbol_decode_map.end())
384 {
385 if(curr_running_disp->get_rx_CRD(i).to_bool())
386 LOG_WARNING << "WARNING : _LTSSM_ : Negative Running Disparity Error in lane " << i;
387 else // Set the disparity according to the symbol received
388 {
389 if(curr_running_disp->calculate_disparity(ireg_in_p[i].range(0,9),0) == 1)
390 curr_running_disp->set_rx_CRD(i,sc_logic(1));
391 else if(curr_running_disp->calculate_disparity(ireg_in_p[i].range(0,9),0) == 0)
392 curr_running_disp->set_rx_CRD(i,sc_logic(0));
393 }
394 }
395 else if(iter_2 != map_table->data_decode_map.end())
396 {
397 if(!curr_running_disp->get_rx_CRD(i).to_bool() && curr_running_disp->calculate_disparity(ireg_in_p[i].range(0,9),0) != 2)
398 LOG_WARNING << "WARNING : _LTSSM_ : Positive Running Disparity Error in lane " << i;
399 else // Set the disparity according to the symbol received
400 {
401 if(curr_running_disp->calculate_disparity(ireg_in_p[i].range(0,9),0) == 1)
402 curr_running_disp->set_rx_CRD(i,sc_logic(1));
403 else if(curr_running_disp->calculate_disparity(ireg_in_p[i].range(0,9),0) == 0)
404 curr_running_disp->set_rx_CRD(i,sc_logic(0));
405 }
406 }
407 else if(iter_3 != map_table->neg_data_decode_map.end())
408 {
409 if(curr_running_disp->get_rx_CRD(i).to_bool() && curr_running_disp->calculate_disparity(ireg_in_p[i].range(0,9),0) != 2)
410 LOG_WARNING << "WARNING : _LTSSM_ : Negative Running Disparity Error in lane " << i;
411 else // Set the disparity according to the symbol received
412 {
413 if(curr_running_disp->calculate_disparity(ireg_in_p[i].range(0,9),0) == 1)
414 curr_running_disp->set_rx_CRD(i,sc_logic(1));
415 else if(curr_running_disp->calculate_disparity(ireg_in_p[i].range(0,9),0) == 0)
416 curr_running_disp->set_rx_CRD(i,sc_logic(0));
417 }
418 }
419 }
420 if(iter2_n != map_table->spec_symbol_decode_map.end())
421 idle_set_negedge[0] = iter2_n->second;
422 else if(iter3_n != map_table->neg_spec_symbol_decode_map.end())
423 idle_set_negedge[0] = iter3_n->second;
424 else if(iter_n != map_table->data_decode_map.end())
425 idle_set_negedge[0] = iter_n->second;
426 else if(iter1_n != map_table->neg_data_decode_map.end())
427 idle_set_negedge[0] = iter1_n->second;
428 }
429 tmp_lfsr = descrambler_i->get_lfsr(0);
430 for(int lane_scram = 0;lane_scram < LINK_WIDTH; lane_scram++)
431 {
432 descrambler_i->start_scramble_reg[lane_scram] = true;
433 }
434 idle_set[0] = descrambler_i->scramble_descramble_all(idle_set[0].to_uint(),0,1);// LFSR moves forward
435
436 /// Check for Logical Idle Patterns
437 if((idle_set[0] == 0x00) && ((init_state == CFG_IDLE) || (init_state == Recovery_Idle))) // Check for Logical Idle Pattern
438 {
439 // IDLE patterns started by the EP
440 idl_count++;
441
442 if(idl_count == 1 && init_state == CFG_IDLE)
443 {
444 received_1xidl_sets = 1;
445 transmit_idl_count = 16;
446 }
447 if(init_state == Recovery_Idle && first_retrain_idle_detection)
448 {
449 transmit_idl_count = 16;
450 first_retrain_idle_detection = false;
451 }
452 if(idl_count == 8)
453 received_8xidl_sets = 1;
454 }
455 }
456
457 /// Check for Disparity when init_state = L0, but pl_top has not yet taken over total control
458 if(!come_next_time && !init_done_rx.read() && (init_state == L0))
459 {
460 iter = map_table->data_decode_map.find(ireg_in_p_p[0].range(0,9).to_uint());
461 iter1 = map_table->neg_data_decode_map.find(ireg_in_p_p[0].range(0,9).to_uint());
462 iter2 = map_table->spec_symbol_decode_map.find(ireg_in_p_p[0].range(0,9).to_uint());
463 iter3 = map_table->neg_spec_symbol_decode_map.find(ireg_in_p_p[0].range(0,9).to_uint());
464 iter_n = map_table->data_decode_map.find(ireg_in_p[0].range(0,9).to_uint());
465 iter1_n = map_table->neg_data_decode_map.find(ireg_in_p[0].range(0,9).to_uint());
466 iter2_n = map_table->spec_symbol_decode_map.find(ireg_in_p[0].range(0,9).to_uint());
467 iter3_n = map_table->neg_spec_symbol_decode_map.find(ireg_in_p[0].range(0,9).to_uint());
468
469 for(i=0;i<LINK_WIDTH;i++)
470 {
471 iter_0 = map_table->spec_symbol_decode_map.find(ireg_in_p_p[i].range(0,9).to_uint());
472 iter_1 = map_table->neg_spec_symbol_decode_map.find(ireg_in_p_p[i].range(0,9).to_uint());
473 iter_2 = map_table->data_decode_map.find(ireg_in_p_p[i].range(0,9).to_uint());
474 iter_3 = map_table->neg_data_decode_map.find(ireg_in_p_p[i].range(0,9).to_uint());
475 if(iter_0 != map_table->spec_symbol_decode_map.end())
476 {
477 if(!curr_running_disp->get_rx_CRD(i).to_bool())
478 LOG_WARNING << "WARNING : _LTSSM_ : Positive Running Disparity Error in lane " << i;
479 else // Set the disparity according to the symbol received
480 {
481 if(curr_running_disp->calculate_disparity(ireg_in_p_p[i].range(0,9),0) == 1)
482 curr_running_disp->set_rx_CRD(i,sc_logic(1));
483 else if(curr_running_disp->calculate_disparity(ireg_in_p_p[i].range(0,9),0) == 0)
484 curr_running_disp->set_rx_CRD(i,sc_logic(0));
485 }
486 }
487 else if(iter_1 != map_table->neg_spec_symbol_decode_map.end())
488 {
489 if(curr_running_disp->get_rx_CRD(i).to_bool())
490 LOG_WARNING << "WARNING : _LTSSM_ : Negative Running Disparity Error in lane " << i;
491 else // Set the disparity according to the symbol received
492 {
493 if(curr_running_disp->calculate_disparity(ireg_in_p_p[i].range(0,9),0) == 1)
494 curr_running_disp->set_rx_CRD(i,sc_logic(1));
495 else if(curr_running_disp->calculate_disparity(ireg_in_p_p[i].range(0,9),0) == 0)
496 curr_running_disp->set_rx_CRD(i,sc_logic(0));
497 }
498 }
499 else if(iter_2 != map_table->data_decode_map.end())
500 {
501 if(!curr_running_disp->get_rx_CRD(i).to_bool() && curr_running_disp->calculate_disparity(ireg_in_p_p[i].range(0,9),0) != 2)
502 LOG_WARNING << "WARNING : _LTSSM_ : Positive Running Disparity Error in lane " << i;
503 else // Set the disparity according to the symbol received
504 {
505 if(curr_running_disp->calculate_disparity(ireg_in_p_p[i].range(0,9),0) == 1)
506 curr_running_disp->set_rx_CRD(i,sc_logic(1));
507 else if(curr_running_disp->calculate_disparity(ireg_in_p_p[i].range(0,9),0) == 0)
508 curr_running_disp->set_rx_CRD(i,sc_logic(0));
509 }
510 }
511 else if(iter_3 != map_table->neg_data_decode_map.end())
512 {
513 if(curr_running_disp->get_rx_CRD(i).to_bool() && curr_running_disp->calculate_disparity(ireg_in_p_p[i].range(0,9),0) != 2)
514 LOG_WARNING << "WARNING : _LTSSM_ : Negative Running Disparity Error in lane " << i;
515 else // Set the disparity according to the symbol received
516 {
517 if(curr_running_disp->calculate_disparity(ireg_in_p_p[i].range(0,9),0) == 1)
518 curr_running_disp->set_rx_CRD(i,sc_logic(1));
519 else if(curr_running_disp->calculate_disparity(ireg_in_p_p[i].range(0,9),0) == 0)
520 curr_running_disp->set_rx_CRD(i,sc_logic(0));
521 }
522 }
523 else if(!first_packet[i])
524 LOG_WARNING << "WARNING : LTSSM : 8b/10b Decode Error";
525 }
526
527 if(iter2 != map_table->spec_symbol_decode_map.end())
528 idle_set[0] = iter2->second;
529 else if(iter3 != map_table->neg_spec_symbol_decode_map.end())
530 idle_set[0] = iter3->second;
531 else if(iter != map_table->data_decode_map.end())
532 idle_set[0] = iter->second;
533 else if(iter1 != map_table->neg_data_decode_map.end())
534 idle_set[0] = iter1->second;
535 tmp_lfsr = descrambler_i->get_lfsr(0);
536 idle_set[0] = descrambler_i->scramble_descramble_all(idle_set[0].to_uint(),0,1);// LFSR moves forward
537 if((idle_set[0] == 0x00)) // Check for Logical Idle Pattern
538 {
539 // IDLE patterns started by the EP
540 idl_count++;
541
542 if(idl_count == 1 && init_state == CFG_IDLE)
543 {
544 received_1xidl_sets = 1;
545 transmit_idl_count = 16;
546 }
547 if(idl_count == 8)
548 received_8xidl_sets = 1;
549 if(init_state == Recovery_Idle && first_retrain_idle_detection)
550 {
551 transmit_idl_count = 16;
552 first_retrain_idle_detection = false;
553 }
554 }
555 }
556
557 /// Shift in values from the bus, for all states other than CFG_IDLE, Recovery_Idle and L0
558 if(start_ordered_set && !come_next_time && (init_state != CFG_IDLE) && (init_state != Recovery_Idle) && (init_state != L0) && !init_done_rx.read()) // Ordered set starts after detecting COM
559 {
560 ts1_2 = (ireg_in_p_p[0],ts1_2.range(159,10)); // Currently only shift in the 0th Lane
561 ts1_2_negedge = (ireg_in_p[0],ts1_2_negedge.range(159,10));
562 fts_set = (ireg_in_p_p[0],fts_set.range(39,10));
563 fts_set_negedge = (ireg_in_p[0],fts_set_negedge.range(39,10));
564 skip_set = (ireg_in_p_p[0],skip_set.range(39,10));
565 skip_set_negedge = (ireg_in_p[0],skip_set.range(39,10));
566 electrical_idle_set = (ireg_in_p_p[0],electrical_idle_set.range(39,10));
567 electrical_idle_set_negedge = (ireg_in_p[0],electrical_idle_set_negedge.range(39,10));
568 symbol_count = symbol_count + 1;
569 for(i=0;i<LINK_WIDTH;i++)
570 {
571 ts1_2_serial[i] = (ireg_in_p_p[i],ts1_2_serial[i].range(159,10));
572 ts1_2_serial_negedge[i] = (ireg_in_p[i],ts1_2_serial_negedge[i].range(159,10));
573 }
574 negedge_skip_this = false;
575 }
576
577 /// Shift in values from the bus for init_state = L0
578 if(start_ordered_set && !come_next_time && init_state == L0 && init_done_rx.read()) // Going into the Recovery state form L0
579 {
580 ts1_2 = (ireg_in_p_p[0],ts1_2.range(159,10)); // Currently only shift in the 0th Lane
581 ts1_2_negedge = (ireg_in_p[0],ts1_2_negedge.range(159,10));
582 fts_set = (ireg_in_p_p[0],fts_set.range(39,10));
583 fts_set_negedge = (ireg_in_p[0],fts_set_negedge.range(39,10));
584 skip_set = (ireg_in_p_p[0],skip_set.range(39,10));
585 skip_set_negedge = (ireg_in_p[0],skip_set.range(39,10));
586 electrical_idle_set = (ireg_in_p_p[0],electrical_idle_set.range(39,10));
587 electrical_idle_set_negedge = (ireg_in_p[0],electrical_idle_set_negedge.range(39,10));
588 symbol_count = symbol_count + 1;
589 for(i=0;i<LINK_WIDTH;i++)
590 {
591 ts1_2_serial[i] = (ireg_in_p_p[i],ts1_2_serial[i].range(159,10));
592 ts1_2_serial_negedge[i] = (ireg_in_p[i],ts1_2_serial_negedge[i].range(159,10));
593 }
594 negedge_skip_this = false;
595 }
596
597 /// Shift in all values for all states other than CFG_IDLE, Recovery_Idle and L0
598 if(!come_next_time && (init_state != CFG_IDLE) && (init_state != Recovery_Idle) && (init_state != L0) && !init_done_rx.read()) // Ordered set starts after detecting COM
599 {
600 iter = map_table->data_decode_map.find(ireg_in_p_p[0].range(0,9).to_uint());
601 iter1 = map_table->neg_data_decode_map.find(ireg_in_p_p[0].range(0,9).to_uint());
602 iter2 = map_table->spec_symbol_decode_map.find(ireg_in_p_p[0].range(0,9).to_uint());
603 iter3 = map_table->neg_spec_symbol_decode_map.find(ireg_in_p_p[0].range(0,9).to_uint());
604 iter_n = map_table->data_decode_map.find(ireg_in_p[0].range(0,9).to_uint());
605 iter1_n = map_table->neg_data_decode_map.find(ireg_in_p[0].range(0,9).to_uint());
606 iter2_n = map_table->spec_symbol_decode_map.find(ireg_in_p[0].range(0,9).to_uint());
607 iter3_n = map_table->neg_spec_symbol_decode_map.find(ireg_in_p[0].range(0,9).to_uint());
608
609 for(i=0;i<LINK_WIDTH;i++)
610 {
611 iter_0 = map_table->spec_symbol_decode_map.find(ireg_in_p_p[i].range(0,9).to_uint());
612 iter_1 = map_table->neg_spec_symbol_decode_map.find(ireg_in_p_p[i].range(0,9).to_uint());
613 iter_2 = map_table->data_decode_map.find(ireg_in_p_p[i].range(0,9).to_uint());
614 iter_3 = map_table->neg_data_decode_map.find(ireg_in_p_p[i].range(0,9).to_uint());
615 iter_4 = map_table->spec_symbol_decode_map.find(ireg_in_p[i].range(0,9).to_uint());
616 iter_5 = map_table->neg_spec_symbol_decode_map.find(ireg_in_p[i].range(0,9).to_uint());
617 iter_6 = map_table->data_decode_map.find(ireg_in_p[i].range(0,9).to_uint());
618 iter_7 = map_table->neg_data_decode_map.find(ireg_in_p[i].range(0,9).to_uint());
619
620 /// For each lane from 0-LINK_WIDTH, set and check for Disparity
621 if(iter_0 != map_table->spec_symbol_decode_map.end())
622 {
623 if(first_packet[i] && frame_boundary_detected) // Set the value. This is the first packet
624 {
625 if(curr_running_disp->calculate_disparity(ireg_in_p_p[i].range(0,9),0) == 1)
626 curr_running_disp->set_rx_CRD(i,sc_logic(1));
627 else if(curr_running_disp->calculate_disparity(ireg_in_p_p[i].range(0,9),0) == 0)
628 curr_running_disp->set_rx_CRD(i,sc_logic(0));
629 else
630 curr_running_disp->set_rx_CRD(i,sc_logic(1));
631 }
632
633 if(!curr_running_disp->get_rx_CRD(i).to_bool() && !first_packet[i] && curr_running_disp->calculate_disparity(ireg_in_p_p[i].range(0,9),0) != 2 && init_state != DETECT_QUIET && init_state != DETECT_ACTIVE){}
634 else if(!first_packet[i])// Set the disparity according to the symbol received
635 {
636 if(curr_running_disp->calculate_disparity(ireg_in_p_p[i].range(0,9),0) == 1)
637 curr_running_disp->set_rx_CRD(i,sc_logic(1));
638 else if(curr_running_disp->calculate_disparity(ireg_in_p_p[i].range(0,9),0) == 0)
639 curr_running_disp->set_rx_CRD(i,sc_logic(0));
640 }
641 if(frame_boundary_detected)
642 first_packet[i] = false;
643 }
644 else if(iter_1 != map_table->neg_spec_symbol_decode_map.end())
645 {
646 if(first_packet[i] && frame_boundary_detected) // Set the value. This is the first packet
647 {
648 if(curr_running_disp->calculate_disparity(ireg_in_p_p[i].range(0,9),0) == 1)
649 curr_running_disp->set_rx_CRD(i,sc_logic(1));
650 else if(curr_running_disp->calculate_disparity(ireg_in_p_p[i].range(0,9),0) == 0)
651 curr_running_disp->set_rx_CRD(i,sc_logic(0));
652 else
653 curr_running_disp->set_rx_CRD(i,sc_logic(0));
654 }
655
656 if(curr_running_disp->get_rx_CRD(i).to_bool() && !first_packet[i] && curr_running_disp->calculate_disparity(ireg_in_p_p[i].range(0,9),0) != 2 && init_state != DETECT_QUIET && init_state != DETECT_ACTIVE){}
657 else if(!first_packet[i])// Set the disparity according to the symbol received
658 {
659 if(curr_running_disp->calculate_disparity(ireg_in_p_p[i].range(0,9),0) == 1)
660 curr_running_disp->set_rx_CRD(i,sc_logic(1));
661 else if(curr_running_disp->calculate_disparity(ireg_in_p_p[i].range(0,9),0) == 0)
662 curr_running_disp->set_rx_CRD(i,sc_logic(0));
663 }
664 if(frame_boundary_detected)
665 first_packet[i] = false;
666 }
667 else if(iter_2 != map_table->data_decode_map.end())
668 {
669
670 if(!curr_running_disp->get_rx_CRD(i).to_bool() && !first_packet[i])
671 {
672 // Also make sure this is not a neutral symbol. Then it it present both in pos
673 // and neg symbol map
674 if(curr_running_disp->calculate_disparity(ireg_in_p_p[i].range(0,9),0) != 2)
675 LOG_WARNING << "WARNING : _LTSSM_ : Positive Running Disparity Error in lane " << i;
676 }
677 else if(!first_packet[i])// Set the disparity according to the symbol received
678 {
679 if(curr_running_disp->calculate_disparity(ireg_in_p_p[i].range(0,9),0) == 1)
680 curr_running_disp->set_rx_CRD(i,sc_logic(1));
681 else if(curr_running_disp->calculate_disparity(ireg_in_p_p[i].range(0,9),0) == 0)
682 curr_running_disp->set_rx_CRD(i,sc_logic(0));
683 }
684 }
685 else if(iter_3 != map_table->neg_data_decode_map.end())
686 {
687
688 if(curr_running_disp->get_rx_CRD(i).to_bool() && !first_packet[i])
689 {
690 if(curr_running_disp->calculate_disparity(ireg_in_p_p[i].range(0,9),0) != 2)
691 LOG_WARNING << "WARNING : _LTSSM_ : Negative Running Disparity Error in lane " << i;
692 }
693 else if(!first_packet[i])// Set the disparity according to the symbol received
694 {
695 if(curr_running_disp->calculate_disparity(ireg_in_p_p[i].range(0,9),0) == 1)
696 curr_running_disp->set_rx_CRD(i,sc_logic(1));
697 else if(curr_running_disp->calculate_disparity(ireg_in_p_p[i].range(0,9),0) == 0)
698 curr_running_disp->set_rx_CRD(i,sc_logic(0));
699 }
700 }
701 else if(iter_4 != map_table->spec_symbol_decode_map.end())
702 {
703 if(first_packet[i] && frame_boundary_detected) // Set the value. This is the first packet
704 {
705 if(curr_running_disp->calculate_disparity(ireg_in_p[i].range(0,9),0) == 1)
706 curr_running_disp->set_rx_CRD(i,sc_logic(1));
707 else if(curr_running_disp->calculate_disparity(ireg_in_p[i].range(0,9),0) == 0)
708 curr_running_disp->set_rx_CRD(i,sc_logic(0));
709 else
710 curr_running_disp->set_rx_CRD(i,sc_logic(1));
711 }
712 if(!curr_running_disp->get_rx_CRD(i).to_bool() && !first_packet[i] && curr_running_disp->calculate_disparity(ireg_in_p[i].range(0,9),0) != 2 && init_state != DETECT_QUIET && init_state != DETECT_ACTIVE)
713 LOG_WARNING << "WARNING : _LTSSM_ : Positive Running Disparity Error in lane " << i;
714 else if(!first_packet[i])
715 {
716 if(curr_running_disp->calculate_disparity(ireg_in_p[i].range(0,9),0) == 1)
717 curr_running_disp->set_rx_CRD(i,sc_logic(1));
718 else if(curr_running_disp->calculate_disparity(ireg_in_p[i].range(0,9),0) == 0)
719 curr_running_disp->set_rx_CRD(i,sc_logic(0));
720 }
721 if(frame_boundary_detected)
722 first_packet[i] = false;
723 }
724 else if(iter_5 != map_table->neg_spec_symbol_decode_map.end())
725 {
726 if(first_packet[i] && frame_boundary_detected) // Set the value. This is the first packet
727 {
728 if(curr_running_disp->calculate_disparity(ireg_in_p[i].range(0,9),0) == 1)
729 curr_running_disp->set_rx_CRD(i,sc_logic(1));
730 else if(curr_running_disp->calculate_disparity(ireg_in_p[i].range(0,9),0) == 0)
731 curr_running_disp->set_rx_CRD(i,sc_logic(0));
732 else
733 curr_running_disp->set_rx_CRD(i,sc_logic(0));
734 }
735
736 if(curr_running_disp->get_rx_CRD(i).to_bool() && !first_packet[i] && curr_running_disp->calculate_disparity(ireg_in_p[i].range(0,9),0) != 2 && init_state != DETECT_QUIET && init_state != DETECT_ACTIVE)
737 LOG_WARNING << "WARNING : _LTSSM_ : Negative Running Disparity Error in lane " << i;
738 else if(!first_packet[i])
739 {
740 if(curr_running_disp->calculate_disparity(ireg_in_p[i].range(0,9),0) == 1)
741 curr_running_disp->set_rx_CRD(i,sc_logic(1));
742 else if(curr_running_disp->calculate_disparity(ireg_in_p[i].range(0,9),0) == 0)
743 curr_running_disp->set_rx_CRD(i,sc_logic(0));
744 }
745 if(frame_boundary_detected)
746 first_packet[i] = false;
747 }
748 else if(iter_6 != map_table->data_decode_map.end())
749 {
750
751 if(!curr_running_disp->get_rx_CRD(i).to_bool() && !first_packet[i])
752 {
753 if(curr_running_disp->calculate_disparity(ireg_in_p[i].range(0,9),0) != 2)
754 LOG_WARNING << "WARNING : _LTSSM_ : Positive Running Disparity Error in lane " << i;
755 }
756 else if(!first_packet[i])
757 {
758 if(curr_running_disp->calculate_disparity(ireg_in_p[i].range(0,9),0) == 1)
759 curr_running_disp->set_rx_CRD(i,sc_logic(1));
760 else if(curr_running_disp->calculate_disparity(ireg_in_p[i].range(0,9),0) == 0)
761 curr_running_disp->set_rx_CRD(i,sc_logic(0));
762 }
763 }
764 else if(iter_7 != map_table->neg_data_decode_map.end())
765 {
766
767 if(curr_running_disp->get_rx_CRD(i).to_bool() && !first_packet[i])
768 {
769 if(curr_running_disp->calculate_disparity(ireg_in_p[i].range(0,9),0) != 2)
770 LOG_WARNING << "WARNING : _LTSSM_ : Negative Running Disparity Error in lane "<< i;
771 }
772 else if(!first_packet[i])
773 {
774 if(curr_running_disp->calculate_disparity(ireg_in_p[i].range(0,9),0) == 1)
775 curr_running_disp->set_rx_CRD(i,sc_logic(1));
776 else if(curr_running_disp->calculate_disparity(ireg_in_p[i].range(0,9),0) == 0)
777 curr_running_disp->set_rx_CRD(i,sc_logic(0));
778 }
779 }
780 else if(!first_packet[i] && frame_boundary_detected && init_state != DETECT_QUIET && init_state != DETECT_ACTIVE && init_state != POLLING_ACTIVE && init_state != POLLING_CONFIG && init_state != CFG_LINKWIDTH_START && init_state != CFG_LINKWIDTH_ACCEPT && !retraining)
781 {
782 LOG_WARNING << "WARNING : LTSSM : 8b/10b Decode Error";
783 }
784 }
785
786 /// Forward the LFSR for the particular rx symbol. But do not descramble the data
787
788 if(iter2 != map_table->spec_symbol_decode_map.end())// && ts1_pattern_received)
789 descrambler_i->scramble_descramble_all(iter2->second,0,1);
790 else if(iter3 != map_table->neg_spec_symbol_decode_map.end())// && ts1_pattern_received)
791 descrambler_i->scramble_descramble_all(iter3->second,0,1);
792 else if(iter != map_table->data_decode_map.end())// && ts1_pattern_received)
793 descrambler_i->scramble_descramble_all(iter->second,0,1);
794 else if(iter1 != map_table->neg_data_decode_map.end())// && ts1_pattern_received)
795 descrambler_i->scramble_descramble_all(iter1->second,0,1);
796
797 else if(iter2_n != map_table->spec_symbol_decode_map.end())// && ts1_pattern_received)
798 descrambler_i->scramble_descramble_all(iter2_n->second,0,1);
799 else if(iter3_n != map_table->neg_spec_symbol_decode_map.end())// && ts1_pattern_received)
800 descrambler_i->scramble_descramble_all(iter3_n->second,0,1);
801 else if(iter_n != map_table->data_decode_map.end())// && ts1_pattern_received)
802 descrambler_i->scramble_descramble_all(iter_n->second,0,1);
803 else if(iter1_n != map_table->neg_data_decode_map.end())// && ts1_pattern_received)
804 descrambler_i->scramble_descramble_all(iter1_n->second,0,1);
805 }
806
807 // TS1/TS2 ordered set occurs only when symbols 6-15 have TS ID
808 // Second symbol after IDLE will show us
809 if(((electrical_idle_set.range(39,30) == IDL_10b || electrical_idle_set_negedge.range(39,30) == IDL_10b) || (electrical_idle_set.range(39,30) == 0x33c) ||electrical_idle_set_negedge.range(39,30) == 0x33c ) && ((electrical_idle_set.range(9,0) == COM_10b) || (electrical_idle_set.range(9,0) == 0x17c) || electrical_idle_set_negedge.range(9,0) == COM_10b || electrical_idle_set_negedge.range(9,0) == 0x17c)) // Received Electrical Idle
810 {
811 if(init_state == L0 || init_state == DISABLED_IDLE)
812 received_electrical_idle = 1;
813 }
814
815 /// SKP Ordered set
816 if(((skip_set.range(39,30) == SKP_10b) || skip_set_negedge.range(39,30) == SKP_10b || (skip_set.range(39,30) == 0x0bc) || skip_set_negedge.range(39,30) == 0xbc) && ((skip_set.range(9,0) == COM_10b) || skip_set_negedge.range(9,0) == COM_10b || (skip_set.range(9,0) == 0x17c) || skip_set_negedge.range(9,0) == 0x17c)) // Received SKP OS
817 {
818 if(init_state == L0)
819 received_skp_ordered_set = 1;
820 }
821
822 if(electrical_idle_constant_voltage_set.range(9,0) == 0x000 && !received_electrical_idle)
823 {
824 constant_voltage_count++;
825 if(init_state == L0 || init_state == Recovery_RcvrLock || init_state == Recovery_RcvrCfg)
826 {
827 received_electrical_idle_constant_voltage = true;
828 constant_voltage_count = 0;
829 }
830 else
831 received_electrical_idle_constant_voltage = false;
832 }
833
834 /// Received TS1/TS2 Ordered Set.
835 if(((ts1_2.range(159,150) == TS1_DELIM || ts1_2_negedge.range(159,150) == TS1_DELIM) || (ts1_2.range(159,150) == TS2_DELIM) || ts1_2_negedge.range(159,150) == TS2_DELIM) && ((ts1_2.range(149,140) == TS1_DELIM || ts1_2_negedge.range(149,140) == TS1_DELIM) || (ts1_2.range(149,140) == TS2_DELIM) || ts1_2_negedge.range(159,150) == TS2_DELIM) && ((ts1_2.range(9,0) == COM_10b || ts1_2_negedge.range(9,0) == COM_10b) || (ts1_2.range(9,0) == 0x17c || ts1_2_negedge.range(9,0) == 0x17c)) || link_ctl_csr.range(5,5) == 0x1) // TS1/TS2 patterns
836 {
837 // TS1/TS2 ordered set detected
838 this_ts1_2 = 1;
839 start_ordered_set = 0;
840 symbol_count = 0;
841 if(init_state == L0) // Stop Transmitting DLLP/TLP and move to Recovery
842 {
843 toRecovery = true;
844 }
845 else
846 toRecovery = false;
847 }
848 else if((fts_set.range(39,30) == FTS_10b) || (skip_set.range(39,30) == SKP_10b) )
849 this_ts1_2 = 0;
850
851 else
852 this_ts1_2 = 0;
853
854 /// Received TS1 Ordered Set
855 if((ts1_2.range(159,150) == TS1_DELIM || ts1_2_negedge.range(159,150) == TS1_DELIM) && (ts1_2.range(149,140) == TS1_DELIM || ts1_2_negedge.range(159,150) == TS1_DELIM) && ((ts1_2.range(9,0) == COM_10b) || ts1_2_negedge.range(9,0) == COM_10b || (ts1_2.range(9,0) == 0x17c) || ts1_2_negedge.range(9,0) == 0x17c) || link_ctl_csr.range(5,5) == 0x1) // TS1 patterns
856 {
857 ts1_count = ts1_count + 1;
858 ts1_set = ts1_2;
859 if(link_ctl_csr.range(5,5) == 0x1)
860 csr_port.write_csr_mask(PEU_CSR_A_LNK_CTL_HW_ADDR,(0x0 << 5),PEU_CSR_LNK_CTL_RETRAIN_MASK);
861 if(init_state == L0) // Stop Transmitting DLLP/TLP and move to Revovery
862 toRecovery = true;
863 else
864 toRecovery = false;
865
866
867 training_ctl = ts1_2.range(50,59); // Get the training control bit to test for Hot Reset
868 if(training_ctl.range(9,0) == 0x1d4 || training_ctl.range(9,0) == 0x22b && init_state == HOT_RESET0)
869 ts1_hot_reset_count++;
870
871 if(ts1_hot_reset_count >= 2)
872 received_2xts1_hot_reset = true;
873 else
874 received_2xts1_hot_reset = false;
875
876
877 for(i=0; i<LINK_WIDTH;i++)
878 {
879 if ( (ts1_2_serial[i].range(19,10) == PAD_10b || ts1_2_serial_negedge[i].range(29,20) == PAD_10b) || (ts1_2_serial[i].range(19,10) == 0x057) || ts1_2_serial_negedge[i].range(29,20) == 0x057) // PAD link
880 {
881 link_field_PAD_ts1_ok++;
882 }
883 }
884 if(link_field_PAD_ts1_ok == LINK_WIDTH)
885 {
886 link_field_is_PAD_ts1++;
887 link_field_PAD_ts1_ok = 0;
888 }
889 else
890 {
891 link_field_PAD_ts1_ok = 0;
892 }
893
894 for(i=0;i<LINK_WIDTH;i++)
895 {
896 if ( (ts1_2_serial[i].range(29,20) == PAD_10b || ts1_2_serial_negedge[i].range(39,30) == PAD_10b) || (ts1_2_serial[i].range(29,20) == 0x057) || ts1_2_serial_negedge[i].range(39,30) == 0x057) // PAD lane
897 {
898 lane_field_PAD_ts1_ok++;
899 if(ts1_2_serial_negedge[i].range(39,30) == PAD_10b || ts1_2_serial_negedge[i].range(39,30) == 0x057)
900 {
901 }
902 }
903 }
904 if(lane_field_PAD_ts1_ok == LINK_WIDTH)
905 {
906 lane_field_is_PAD_ts1++;
907 lane_field_PAD_ts1_ok = 0;
908 }
909 else
910 {
911 lane_field_PAD_ts1_ok = 0;
912 }
913
914 for(i=0;i<LINK_WIDTH;i++)
915 {
916 if((ts1_2_serial[i].range(10,19) == encoded_value[0] || ts1_2_serial_negedge[i].range(20,29) == encoded_value[0]) || (ts1_2_serial[i].range(10,19) == neg_encoded_value[0]) || ts1_2_serial_negedge[i].range(20,29) == neg_encoded_value[0]) // non PAD link #
917 {
918 link_field_non_PAD_ts1_ok++;
919 }
920 if(ts1_2_serial_negedge[i].range(20,29) == encoded_value[0] || ts1_2_serial_negedge[i].range(20,29) == neg_encoded_value[0])
921 {
922 }
923 }
924 if(link_field_non_PAD_ts1_ok == LINK_WIDTH || link_field_non_PAD_ts1_ok > 0)
925 {
926 link_field_is_non_PAD_ts1++;
927 link_field_non_PAD_ts1_ok = 0;
928 }
929 else
930 link_field_non_PAD_ts1_ok = 0;
931
932 for(i=0;i<LINK_WIDTH;i++)
933 {
934 if((ts1_2_serial[i].range(20,29) == encoded_value[i] || ts1_2_serial_negedge[i].range(30,39) == encoded_value[i] || ts1_2_serial_negedge[i].range(30,39) == neg_encoded_value[i]) || (ts1_2_serial[i].range(20,29) == neg_encoded_value[i])) // Each lane will have an unique lane # which is non PAD
935 {
936 if(ts1_2_serial_negedge[i].range(30,39) == encoded_value[i] || ts1_2_serial_negedge[i].range(30,39) == neg_encoded_value[i])
937 {
938 }
939 lane_num_ok++;
940 }
941 else if(((ts1_2_serial[i].range(29,20) != PAD_10b) && (ts1_2_serial[i].range(29,20) != 0x057)) && (ts1_2_serial_negedge[i].range(29,20) != PAD_10b && ts1_2_serial_negedge[i].range(29,20) != 0x057)) // Non pAD, but different Lane Num // PAD lane. Chance to move to CFG_LANENUM_WAIT
942 {
943 if((ts1_2_serial[i].range(29,20) != PAD_10b) && (ts1_2_serial[i].range(29,20) != 0x057))
944 ts1_lane_diff_non_PAD_tmp[i] = ts1_2_serial[i].range(20,29);
945 else
946 ts1_lane_diff_non_PAD_tmp[i] = ts1_2_serial_negedge[i].range(30,39);
947 diff_lane_num_ok++;
948 }
949 else if(((ts1_2_serial[i].range(20,29) != encoded_value[i]) || (ts1_2_serial[i].range(20,29) != neg_encoded_value[i])) && ((ts1_2_serial[i].range(29,20) != PAD_10b) && (ts1_2_serial[i].range(29,20) != 0x057)))
950 {
951 diff_lane_num_ok++;
952 }
953 }
954
955 if(lane_num_ok == LINK_WIDTH || lane_num_ok > 0) // All lanes match the lane number
956 {
957 lane_field_is_non_PAD_ts1++;
958 lane_num_ok = 0;
959 if(link_field_is_non_PAD_ts1 > 0 && init_state == CFG_LANENUM_WAIT)
960 {
961 from_cfg_lanenum_wait = false;
962 move_to_cfg_lanenum_accept = true;
963 }
964 }
965 else if(diff_lane_num_ok == 2 && link_field_is_non_PAD_ts1 == 2 && (init_state == CFG_LANENUM_ACCEPT) || (init_state == CFG_LINKWIDTH_ACCEPT))
966 {
967 move_to_cfg_lanenum_wait = 1; // Move to CFG_LANENUM_WAIT
968 diff_lane_num_ok = 0;
969 lane_num_ok = 0;
970 for(i=0;i<LINK_WIDTH;i++)
971 {
972 ts2_lane_diff_non_PAD[i] = ts1_lane_diff_non_PAD_tmp[i];
973 ts1_lane_diff_non_PAD[i] = ts1_lane_diff_non_PAD_tmp[i];
974 }
975 }
976 else if((diff_lane_num_ok > 0 || lane_field_is_non_PAD_ts1 > 0) && link_field_is_non_PAD_ts1 > 0 && init_state == CFG_LANENUM_WAIT)
977 {
978 if(lane_field_is_non_PAD_ts1 > 0)
979 from_cfg_lanenum_wait = false;
980 move_to_cfg_lanenum_accept = 1;
981 move_to_cfg_lanenum_wait = false;
982 lane_field_is_non_PAD_ts1 = 0;
983 lane_num_ok = 0;
984 diff_lane_num_ok = 0;
985 }
986 else if(lane_num_ok == 0 && diff_lane_num_ok == 0)
987 {
988 lane_field_is_non_PAD_ts1 = 0;
989 lane_num_ok = 0;
990 diff_lane_num_ok = 0;
991 }
992
993 // Check for disable bit/scrambling bit/loopback bit etc in the link_ctl symbol
994 if(ts1_2.range(159,150) == TS1_DELIM && ts1_2.range(149,140) == TS1_DELIM)
995 {
996 iter = map_table->data_decode_map.find(ts1_2.range(50,59).to_uint());
997 iter1 = map_table->neg_data_decode_map.find(ts1_2.range(50,59).to_uint());
998 if(iter != map_table->data_decode_map.end())
999 {
1000 ts1_trn_ctrl = iter->second;
1001 }
1002 else ts1_trn_ctrl = iter1->second;
1003 }
1004 else
1005 {
1006 iter = map_table->data_decode_map.find(ts1_2_negedge.range(60,69).to_uint());
1007 iter1 = map_table->neg_data_decode_map.find(ts1_2_negedge.range(60,69).to_uint());
1008 if(iter != map_table->data_decode_map.end())
1009 {
1010 ts1_trn_ctrl = iter->second;
1011 }
1012 else ts1_trn_ctrl = iter1->second;
1013 }
1014
1015 if(ts1_trn_ctrl.range(1,1) == 0x1)
1016 disable_link_reg = true;
1017 else disable_link_reg = false;
1018
1019 if(ts1_trn_ctrl.range(3,3) == 0x1)
1020 disable_scrambling_reg = true;
1021 else disable_scrambling_reg = false;
1022
1023 if(disable_link_reg)
1024 ts1_disable_link_count++;
1025 else
1026 ts1_disable_link_count = 0;
1027
1028 if(disable_scrambling_reg)
1029 ts1_disable_scrambling_count++;
1030 else
1031 ts1_disable_scrambling_count = 0;
1032
1033 if(ts1_count == 1)
1034 {
1035 transmit_ts1_count = 17; //Workaround for Fast training.
1036 received_1xts1_sets = 1;
1037 enter_drain_state = false;
1038 }
1039
1040 if(ts1_count == 8)
1041 {
1042 received_8xts1_sets = 1;
1043 }
1044 else
1045 received_8xts1_sets = 0;
1046 }
1047
1048 /// TS2 Ordered Set Received
1049 if((ts1_2.range(159,150) == TS2_DELIM || ts1_2_negedge.range(159,150) == TS2_DELIM) && (ts1_2.range(149,140) == TS2_DELIM || ts1_2_negedge.range(149,140) == TS2_DELIM) && ((ts1_2.range(9,0) == COM_10b || ts1_2_negedge.range(9,0) == COM_10b) || (ts1_2.range(9,0) == 0x17c) || ts1_2_negedge.range(9,0) == 0x17c)) // TS2 patterns
1050 {
1051 ts2_set = ts1_2;
1052 ts2_count = ts2_count + 1;
1053
1054 for(i=0;i<LINK_WIDTH;i++)
1055 {
1056 if ( (ts1_2_serial[i].range(19,10) == PAD_10b || ts1_2_serial_negedge[i].range(29,20) == PAD_10b) || (ts1_2_serial[i].range(19,10) == 0x057) || ts1_2_serial_negedge[i].range(29,20) == 0x057) // Link PAD
1057 {
1058 link_field_PAD_ts2_ok++;
1059 }
1060 }
1061 if(link_field_PAD_ts2_ok == LINK_WIDTH)
1062 {
1063 link_field_is_PAD_ts2++;
1064 link_field_PAD_ts2_ok = 0;
1065 }
1066 else
1067 {
1068 link_field_PAD_ts2_ok = 0;
1069 }
1070
1071 for(i=0;i<LINK_WIDTH;i++)
1072 {
1073 if ( (ts1_2_serial[i].range(29,20) == PAD_10b || ts1_2_serial_negedge[i].range(39,30) == PAD_10b) || (ts1_2_serial[i].range(29,20) == 0x057) || ts1_2_serial_negedge[i].range(39,30) == 0x057) // Lane PAD
1074 {
1075 lane_field_PAD_ts2_ok++;
1076 }
1077 }
1078 if(lane_field_PAD_ts2_ok == LINK_WIDTH)
1079 {
1080 lane_field_is_PAD_ts2++;
1081 lane_field_PAD_ts2_ok = 0;
1082 }
1083 else
1084 {
1085 lane_field_PAD_ts2_ok = 0;
1086 }
1087
1088 for(i=0;i<LINK_WIDTH;i++)
1089 {
1090 if((ts1_2_serial[i].range(19,10) != PAD_10b && ts1_2_serial_negedge[i].range(29,20) != PAD_10b) && (ts1_2_serial[i].range(19,10) != PAD_10b) || ts1_2_serial_negedge[i].range(29,20) != PAD_10b) // non PAD link # received
1091 {
1092 link_field_non_PAD_ts2_ok++;
1093 }
1094 }
1095
1096 if(link_field_non_PAD_ts2_ok == LINK_WIDTH)
1097 {
1098 link_field_is_non_PAD_ts2++;
1099 link_field_non_PAD_ts2_ok = 0;
1100 }
1101 else
1102 {
1103 link_field_non_PAD_ts2_ok = 0;
1104 }
1105
1106 for(i=0;i<LINK_WIDTH;i++)
1107 {
1108 if((ts1_2_serial[i].range(20,29) == encoded_value[i] || ts1_2_serial_negedge[i].range(30,39) == encoded_value[i]) || (ts1_2_serial[i].range(20,29) == neg_encoded_value[i]) || ts1_2_serial_negedge[i].range(30,39) == neg_encoded_value[i]) // Each lane will have an unique lane # which is non PAD
1109 {
1110 lane_num_ok++;
1111 }
1112 else if(((ts1_2_serial[i].range(29,20) != PAD_10b) && (ts1_2_serial[i].range(29,20) != 0x057)) || (ts1_2_serial_negedge[i].range(39,30) != PAD_10b) && (ts1_2_serial_negedge[i].range(39,30) != 0x057)) // Non pAD, but different Lane Num
1113 {
1114 lane_num_ok++;
1115 }
1116 }
1117
1118 if(lane_num_ok == LINK_WIDTH) // All lanes match the lane number
1119 {
1120 lane_field_is_non_PAD_ts2++;
1121 lane_num_ok = 0;
1122 }
1123 else if(lane_num_ok == 0)
1124 {
1125 lane_num_ok = 0;
1126 }
1127
1128 if(ts2_count == 1)
1129 {
1130 transmit_ts2_count = 17;
1131 received_1xts2_sets = 1;
1132 }
1133
1134 if ( ts2_count == 9 )
1135 {
1136 received_8xts2_sets=1;
1137 }
1138 else
1139 received_8xts2_sets=0;
1140
1141 if(ts2_count >= 2 && init_state == CFG_LANENUM_WAIT)
1142 {
1143 move_to_cfg_lanenum_accept = 1;
1144 if(lane_field_is_non_PAD_ts2 > 0)
1145 from_cfg_lanenum_wait = false;
1146 }
1147 }
1148
1149 if(this_ts1_2) // One TS1/TS2 pattern received.. Reset this vector and receive the next TS1/TS2 pattern
1150 {
1151 ts1_2.range(159,0) = 0x0000000000000000000000000000000000000000;
1152 }
1153 }
1154
1155 if(stage_init_state_rx)
1156 {
1157 init_done_rx.write(true);
1158 }
1159
1160 if(write_init_done_rx && frame_boundary_reg.read())
1161 {
1162 stage_init_state_rx = true;
1163 }
1164 wait(SC_ZERO_TIME); // Transmit 2 last frame to take care of race condition in the pl_top
1165 }
1166 else
1167 {
1168 ts1_2 = 0x0000000000000000000000000000000000000000;
1169 ts1_2_negedge = 0x0000000000000000000000000000000000000000;
1170 transmitted_1024xts1_2sets = 0;
1171 transmitted_16xts2_sets = 0;
1172 transmitted_16xidl_sets = 0;
1173 transmitted_ts1_pattern = 0;
1174 ts1_pattern_bit = 0;
1175 ts2_pattern_bit = 0;
1176 idle_pattern_bit = 0;
1177 received_8xts2_sets = 0;
1178 received_8xts1_sets = 0;
1179 received_1xts1_sets = 0;
1180 received_1xts2_sets = 0;
1181 ts1_non_pad_link_bit = 0;
1182 symbol_num = 0;
1183 link_field_is_PAD_ts1 = 0;
1184 lane_field_is_PAD_ts1 = 0;
1185 link_field_is_PAD_ts2 = 0;
1186 lane_field_is_PAD_ts2 = 0;
1187 link_field_is_non_PAD_ts1 = 0;
1188 lane_field_is_non_PAD_ts1 = 0;
1189 link_field_is_non_PAD_ts2 = 0;
1190 lane_field_is_non_PAD_ts2 = 0;
1191 link_field_PAD_ts1_ok = 0;
1192 link_field_PAD_ts2_ok = 0;
1193 lane_field_PAD_ts1_ok = 0;
1194 lane_field_PAD_ts2_ok = 0;
1195 elec_idle_pattern_bit = 0;
1196 com_detected_tx = false;
1197 start_frame_boundary_tx = false;
1198 frame_boundary_tx_counter = 0;
1199 frame_boundary_detected = 0;
1200 sym_counter = 0;
1201 lock_counter = 0;
1202 lock_negedge_clock = false;
1203 com_detected = false;
1204 for(i=0;i<LINK_WIDTH;i++)
1205 {
1206 first_packet[i] = true;
1207 }
1208 }
1209 wait(link_clk.negedge_event());
1210 }
1211}
1212
1213/// Set the Delimiters for TS1/TS2 patterns for different state registers
1214/// Useful for reusability
1215void ltssm::set_delim_value(int set,int i)
1216{
1217 switch(set)
1218 {
1219 case DISABLED_SET :
1220 {
1221 disabled_set[i].range(159,150) = TS1_DELIM;
1222 disabled_set[i].range(149,140) = TS1_DELIM;
1223 disabled_set[i].range(139,130) = TS1_DELIM;
1224 disabled_set[i].range(129,120) = TS1_DELIM;
1225 disabled_set[i].range(119,110) = TS1_DELIM;
1226 disabled_set[i].range(109,100) = TS1_DELIM;
1227 disabled_set[i].range(99,90) = TS1_DELIM;
1228 disabled_set[i].range(89,80) = TS1_DELIM;
1229 disabled_set[i].range(79,70) = TS1_DELIM;
1230 disabled_set[i].range(69,60) = TS1_DELIM;
1231 }
1232 case TS1_SET_CONST :
1233 {
1234 ts1_set_const[i].range(159,150) = TS1_DELIM;
1235 ts1_set_const[i].range(149,140) = TS1_DELIM;
1236 ts1_set_const[i].range(139,130) = TS1_DELIM;
1237 ts1_set_const[i].range(129,120) = TS1_DELIM;
1238 ts1_set_const[i].range(119,110) = TS1_DELIM;
1239 ts1_set_const[i].range(109,100) = TS1_DELIM;
1240 ts1_set_const[i].range(99,90) = TS1_DELIM;
1241 ts1_set_const[i].range(89,80) = TS1_DELIM;
1242 ts1_set_const[i].range(79,70) = TS1_DELIM;
1243 ts1_set_const[i].range(69,60) = TS1_DELIM;
1244 }
1245 case TS2_SET_CONST :
1246 {
1247 ts2_set_const[i].range(159,150) = TS2_DELIM;
1248 ts2_set_const[i].range(149,140) = TS2_DELIM;
1249 ts2_set_const[i].range(139,130) = TS2_DELIM;
1250 ts2_set_const[i].range(129,120) = TS2_DELIM;
1251 ts2_set_const[i].range(119,110) = TS2_DELIM;
1252 ts2_set_const[i].range(109,100) = TS2_DELIM;
1253 ts2_set_const[i].range(99,90) = TS2_DELIM;
1254 ts2_set_const[i].range(89,80) = TS2_DELIM;
1255 ts2_set_const[i].range(79,70) = TS2_DELIM;
1256 ts2_set_const[i].range(69,60) = TS2_DELIM;
1257 }
1258 case TS1_LINK_NUM_NON_PAD :
1259 {
1260 ts1_link_num_non_PAD[i].range(159,150) = TS1_DELIM;
1261 ts1_link_num_non_PAD[i].range(149,140) = TS1_DELIM;
1262 ts1_link_num_non_PAD[i].range(139,130) = TS1_DELIM;
1263 ts1_link_num_non_PAD[i].range(129,120) = TS1_DELIM;
1264 ts1_link_num_non_PAD[i].range(119,110) = TS1_DELIM;
1265 ts1_link_num_non_PAD[i].range(109,100) = TS1_DELIM;
1266 ts1_link_num_non_PAD[i].range(99,90) = TS1_DELIM;
1267 ts1_link_num_non_PAD[i].range(89,80) = TS1_DELIM;
1268 ts1_link_num_non_PAD[i].range(79,70) = TS1_DELIM;
1269 ts1_link_num_non_PAD[i].range(69,60) = TS1_DELIM;
1270 }
1271 case TS1_LINK_LANE_NON_PAD :
1272 {
1273 ts1_link_lane_non_PAD[i].range(159,150) = TS1_DELIM;
1274 ts1_link_lane_non_PAD[i].range(149,140) = TS1_DELIM;
1275 ts1_link_lane_non_PAD[i].range(139,130) = TS1_DELIM;
1276 ts1_link_lane_non_PAD[i].range(129,120) = TS1_DELIM;
1277 ts1_link_lane_non_PAD[i].range(119,110) = TS1_DELIM;
1278 ts1_link_lane_non_PAD[i].range(109,100) = TS1_DELIM;
1279 ts1_link_lane_non_PAD[i].range(99,90) = TS1_DELIM;
1280 ts1_link_lane_non_PAD[i].range(89,80) = TS1_DELIM;
1281 ts1_link_lane_non_PAD[i].range(79,70) = TS1_DELIM;
1282 ts1_link_lane_non_PAD[i].range(69,60) = TS1_DELIM;
1283 }
1284 case TS2_LINK_LANE_NON_PAD :
1285 {
1286 ts2_link_lane_non_PAD[i].range(159,150) = TS2_DELIM;
1287 ts2_link_lane_non_PAD[i].range(149,140) = TS2_DELIM;
1288 ts2_link_lane_non_PAD[i].range(139,130) = TS2_DELIM;
1289 ts2_link_lane_non_PAD[i].range(129,120) = TS2_DELIM;
1290 ts2_link_lane_non_PAD[i].range(119,110) = TS2_DELIM;
1291 ts2_link_lane_non_PAD[i].range(109,100) = TS2_DELIM;
1292 ts2_link_lane_non_PAD[i].range(99,90) = TS2_DELIM;
1293 ts2_link_lane_non_PAD[i].range(89,80) = TS2_DELIM;
1294 ts2_link_lane_non_PAD[i].range(79,70) = TS2_DELIM;
1295 ts2_link_lane_non_PAD[i].range(69,60) = TS2_DELIM;
1296 }
1297 }
1298}
1299
1300/// This function can be useful if you want to reset all variables at the same time. Use with CAUTION
1301void ltssm::reset_var_detect_quiet()
1302{
1303 link_field_is_PAD_ts1 = 0;
1304 link_field_is_PAD_ts2 = 0;
1305 lane_field_is_PAD_ts1 = 0;
1306 lane_field_is_PAD_ts2 = 0;
1307 link_field_is_non_PAD_ts1 = 0;
1308 lane_field_is_non_PAD_ts1 = 0;
1309 link_field_is_non_PAD_ts2 = 0;
1310 lane_field_is_non_PAD_ts2 = 0;
1311 transmitted_16xts2_sets = 0;
1312 transmitted_1024xts1_2sets = 0;
1313 ts1_count = 0;
1314 ts2_count = 0;
1315 received_1xts2_sets = 0;
1316 received_8xts2_sets = 0;
1317 received_1xts1_sets = 0;
1318 received_8xts1_sets = 0;
1319 received_1xidl_sets = 0;
1320 received_8xidl_sets = 0;
1321 received_electrical_idle = 0;
1322 received_electrical_idle_constant_voltage = 0;
1323 received_2xts1_hot_reset = 0;
1324 received_skp_ordered_set = 0;
1325 transmitted_1024xts1_2sets = 0;
1326
1327}
1328/// Main block to take care of transmission
1329void ltssm::tx_block()
1330{
1331 int i,k;
1332 map<int,int>::iterator iter,iter1,iter2;
1333 unsigned short tmp_lfsr;
1334 sc_lv<10> scramble_pattern = 0x000;
1335
1336 while(true)
1337 {
1338 if(reset_por_l.read()) // System has come out of reset
1339 {
1340 if(init_state == DISABLED_ENTRY) // Transmitter for DISABLED_ENTRY state
1341 {
1342 if(ts1_non_pad_link_bit == 0 && ts1_disabled_bit == 0 && ts2_pattern_bit == 0)
1343 {
1344 for(i=0;i<LINK_WIDTH;i++)
1345 {
1346 if(curr_running_disp->get_CRD(i).to_bool())
1347 {
1348 iter = map_table->spec_symbol_map.find(K28_5);
1349 disabled_set[i].range(0,9) = iter->second;
1350 set_delim_value(DISABLED_SET,i);
1351 }
1352 else if(!curr_running_disp->get_CRD(i).to_bool())
1353 {
1354 iter = map_table->spec_symbol_map.find(K28_5);
1355 disabled_set[i].range(0,9) = ~(iter->second);
1356 set_delim_value(DISABLED_SET,i);
1357 }
1358 if(curr_running_disp->calculate_disparity(disabled_set[i].range(0,9),0) == 1)
1359 {
1360 curr_running_disp->set_CRD(i,sc_logic(1));
1361 }
1362 else if(curr_running_disp->calculate_disparity(disabled_set[i].range(0,9),0) == 0)
1363 {
1364 curr_running_disp->set_CRD(i,sc_logic(0));
1365 }
1366 }
1367 for(i=0;i<LINK_WIDTH;i++)
1368 {
1369 if(curr_running_disp->get_CRD(i).to_bool())
1370 {
1371 iter = map_table->spec_symbol_map.find(K23_7);
1372 ts1_set_const[i].range(10,19) = iter->second; // Neutral disparity
1373 iter = map_table->spec_symbol_map.find(K23_7);
1374 ts1_set_const[i].range(20,29) = iter->second; // Neutral
1375 ts1_set_const[i].range(30,39) = 0x15a; // Neutral
1376 iter = map_table->data_encode_map.find(D2_0);
1377 ts1_set_const[i].range(40,49) = iter->second; // Neutral
1378 iter = map_table->data_encode_map.find(D2_0);
1379 ts1_set_const[i].range(50,59) = iter->second; // Neutral
1380 }
1381 else if(!curr_running_disp->get_CRD(i).to_bool())
1382 {
1383 iter = map_table->spec_symbol_map.find(K23_7);
1384 ts1_set_const[i].range(10,19) = ~(iter->second); // Neutral disparity
1385 iter = map_table->spec_symbol_map.find(K23_7);
1386 ts1_set_const[i].range(20,29) = ~(iter->second); // Neutral
1387 ts1_set_const[i].range(30,39) = TS2_DELIM; // Neutral
1388 iter = map_table->neg_data_encode_map.find(D2_0);
1389 ts1_set_const[i].range(40,49) = (iter->second); // Neutral
1390 iter = map_table->neg_data_encode_map.find(D2_0);
1391 ts1_set_const[i].range(50,59) = (iter->second); // Neutral
1392 }
1393 }
1394 }
1395 /// Go ahead with the disabled state transmission
1396 if(ts1_non_pad_link_bit == 0 && ts2_pattern_bit == 0)
1397 {
1398 for(i=0;i<LINK_WIDTH;i++)
1399 {
1400 if(LINK_WIDTH == 1)
1401 out_reg = (disabled_set[i].range(ts1_disabled_bit,ts1_disabled_bit));
1402 else
1403 out_reg = (disabled_set[i].range(ts1_disabled_bit,ts1_disabled_bit),out_reg.range(LINK_WIDTH-1,1));
1404 out_reg_bar = ~out_reg;
1405 }
1406 if(ts1_disabled_bit == 0) // COM
1407 scrambler_i->scramble_descramble_all(K28_5,1,1);
1408 else if((ts1_disabled_bit % 10) == 0)
1409 {
1410 for(int lane_scram = 0;lane_scram < LINK_WIDTH; lane_scram++)
1411 {
1412 scrambler_i->start_scramble_reg[lane_scram] = true;
1413 scrambler_i->scramble_descramble(0x00,1,0,lane_scram); // Move forward the LFSR
1414 }
1415 }
1416 ts1_disabled_bit += 1;
1417 ts1_disabled_bit %= 160;
1418 if(ts1_disabled_bit == 0) // Transmitted a TS1 pattern with disable bit asserted
1419 {
1420 ts1_disabled_pattern_count++;
1421 if(ts1_disabled_pattern_count == 16)
1422 transmitted_16xts1_disabled = true;
1423 }
1424 }
1425 /// Complete the previous transmission
1426 else if(ts1_non_pad_link_bit != 0)
1427 {
1428 for(i=0;i<LINK_WIDTH;i++)
1429 {
1430 if(LINK_WIDTH == 1)
1431 out_reg = (ts1_link_num_non_PAD[i].range(ts1_non_pad_link_bit,ts1_non_pad_link_bit));
1432 else
1433 out_reg = (ts1_link_num_non_PAD[i].range(ts1_non_pad_link_bit,ts1_non_pad_link_bit),out_reg.range(LINK_WIDTH-1,1));
1434 out_reg_bar = ~out_reg;
1435 }
1436 if(ts1_non_pad_link_bit == 0)
1437 scrambler_i->scramble_descramble_all(K28_5,1,1);
1438 else if((ts1_non_pad_link_bit % 10) == 0)
1439 {
1440 for(int lane_scram = 0;lane_scram < LINK_WIDTH; lane_scram++)
1441 {
1442 scrambler_i->start_scramble_reg[lane_scram] = true;
1443 scrambler_i->scramble_descramble(0x00,1,0,lane_scram); // Move forward the LFSR
1444 }
1445 }
1446
1447 ts1_non_pad_link_bit += 1;
1448 ts1_non_pad_link_bit %= 160;
1449 }
1450 /// Complete the previous transmission
1451 else if(ts2_pattern_bit != 0)
1452 {
1453 for(i=0;i<LINK_WIDTH;i++)
1454 {
1455 if(LINK_WIDTH == 1)
1456 out_reg = (ts2_set_const[i].range(ts2_pattern_bit,ts2_pattern_bit));
1457 else
1458 out_reg = (ts2_set_const[i].range(ts2_pattern_bit,ts2_pattern_bit),out_reg.range(LINK_WIDTH-1,1));
1459 out_reg_bar = ~out_reg;
1460 }
1461 if(ts2_pattern_bit == 0)
1462 scrambler_i->scramble_descramble_all(K28_5,1,1);
1463 else if((ts2_pattern_bit % 10) == 0)
1464 {
1465 for(int lane_scram = 0;lane_scram < LINK_WIDTH; lane_scram++)
1466 {
1467 scrambler_i->start_scramble_reg[lane_scram] = true;
1468 scrambler_i->scramble_descramble(0x00,1,0,lane_scram); // Move forward the LFSR
1469 }
1470 }
1471
1472 ts2_pattern_bit += 1;
1473 ts2_pattern_bit %= 160;
1474 }
1475 }
1476
1477 /// If the init_state is DETECT_QUIET/DETECT_ACTIVE/DISABLED, finish off the remaining transfers from the previous state
1478 /// and then start sending DISABLE patterns
1479 if(init_state == DETECT_QUIET || init_state == DETECT_ACTIVE || init_state == DISABLED_IDLE || init_state == DISABLED) // Start this, aligned with the Rx frame_boundary
1480 {
1481 /// Send Electrical idle patterns
1482 if(elec_idle_pattern_bit == 0 && ts1_pattern_bit == 0 && ts2_pattern_bit == 0 && ts2_failover_pattern_bit == 0 && ts1_non_pad_link_bit == 0 && ts1_non_pad_link_lane == 0 && symbol_num == 0 && idle_pattern_bit == 0 && ts1_disabled_bit == 0 && ts1_non_pad_lane_bit == 0 && ts1_non_pad_diff_lane_bit == 0)
1483 {
1484 for(i=0;i<LINK_WIDTH;i++)
1485 {
1486 if(curr_running_disp->get_CRD(i).to_bool())
1487 {
1488 iter = map_table->spec_symbol_map.find(K28_5);
1489 elec_idle_set[i].range(0,9) = iter->second;
1490 }
1491 else if(!curr_running_disp->get_CRD(i).to_bool())
1492 {
1493 iter = map_table->spec_symbol_map.find(K28_5);
1494 elec_idle_set[i].range(0,9) = ~(iter->second);
1495 }
1496 if(curr_running_disp->calculate_disparity(elec_idle_set[i].range(0,9),0) == 1)
1497 {
1498 curr_running_disp->set_CRD(i,sc_logic(1));
1499 }
1500 else if(curr_running_disp->calculate_disparity(elec_idle_set[i].range(0,9),0) == 0)
1501 {
1502 curr_running_disp->set_CRD(i,sc_logic(0));
1503 }
1504
1505 }
1506 for(i=0;i<LINK_WIDTH;i++)
1507 {
1508 if(curr_running_disp->get_CRD(i).to_bool())
1509 {
1510 iter = map_table->spec_symbol_map.find(K28_3);
1511 elec_idle_set[i].range(10,19) = iter->second;
1512 }
1513 else if(!curr_running_disp->get_CRD(i).to_bool())
1514 {
1515 iter = map_table->spec_symbol_map.find(K28_3);
1516 elec_idle_set[i].range(10,19) = ~(iter->second);
1517 }
1518 if(curr_running_disp->calculate_disparity(elec_idle_set[i].range(10,19),0) == 1)
1519 {
1520 curr_running_disp->set_CRD(i,sc_logic(1));
1521 }
1522 else if(curr_running_disp->calculate_disparity(elec_idle_set[i].range(10,19),0) == 0)
1523 {
1524 curr_running_disp->set_CRD(i,sc_logic(0));
1525 }
1526
1527 }
1528 for(i=0;i<LINK_WIDTH;i++)
1529 {
1530 if(curr_running_disp->get_CRD(i).to_bool())
1531 {
1532 iter = map_table->spec_symbol_map.find(K28_3);
1533 elec_idle_set[i].range(20,29) = iter->second;
1534 }
1535 else if(!curr_running_disp->get_CRD(i).to_bool())
1536 {
1537 iter = map_table->spec_symbol_map.find(K28_3);
1538 elec_idle_set[i].range(20,29) = ~(iter->second);
1539 }
1540 if(curr_running_disp->calculate_disparity(elec_idle_set[i].range(20,29),0) == 1)
1541 {
1542 curr_running_disp->set_CRD(i,sc_logic(1));
1543 }
1544 else if(curr_running_disp->calculate_disparity(elec_idle_set[i].range(20,29),0) == 0)
1545 {
1546 curr_running_disp->set_CRD(i,sc_logic(0));
1547 }
1548
1549 }
1550 for(i=0;i<LINK_WIDTH;i++)
1551 {
1552 if(curr_running_disp->get_CRD(i).to_bool())
1553 {
1554 iter = map_table->spec_symbol_map.find(K28_3);
1555 elec_idle_set[i].range(30,39) = iter->second;
1556 }
1557 else if(!curr_running_disp->get_CRD(i).to_bool())
1558 {
1559 iter = map_table->spec_symbol_map.find(K28_3);
1560 elec_idle_set[i].range(30,39) = ~(iter->second);
1561 }
1562 if(curr_running_disp->calculate_disparity(elec_idle_set[i].range(30,39),0) == 1)
1563 {
1564 curr_running_disp->set_CRD(i,sc_logic(1));
1565 }
1566 else if(curr_running_disp->calculate_disparity(elec_idle_set[i].range(30,39),0) == 0)
1567 {
1568 curr_running_disp->set_CRD(i,sc_logic(0));
1569 }
1570
1571 }
1572 }
1573 /// Send Electrical IDLE ordered set
1574 if(ts1_pattern_bit == 0 && ts2_pattern_bit == 0 && ts2_failover_pattern_bit == 0 && ts1_non_pad_link_bit == 0 && ts1_non_pad_link_lane == 0 && symbol_num == 0 && idle_pattern_bit == 0 && ts1_non_pad_lane_bit == 0 && ts1_non_pad_diff_lane_bit == 0)
1575 {
1576 for(i=0;i<LINK_WIDTH;i++)
1577 {
1578 if(LINK_WIDTH == 1)
1579 out_reg = (elec_idle_set[i].range(elec_idle_pattern_bit,elec_idle_pattern_bit));
1580 else
1581 out_reg = (elec_idle_set[i].range(elec_idle_pattern_bit,elec_idle_pattern_bit),out_reg.range(LINK_WIDTH-1,1));
1582 out_reg_bar = ~out_reg;
1583 }
1584 if(elec_idle_pattern_bit == 0) // COM
1585 scrambler_i->scramble_descramble_all(K28_5,1,1);
1586 else if((elec_idle_pattern_bit % 10) == 0)
1587 {
1588 for(int lane_scram = 0;lane_scram < LINK_WIDTH; lane_scram++)
1589 {
1590 scrambler_i->start_scramble_reg[lane_scram] = true;
1591 scrambler_i->scramble_descramble(0x00,1,0,lane_scram); // Move forward the LFSR
1592 }
1593 }
1594 elec_idle_pattern_bit += 1;
1595 elec_idle_pattern_bit %= 40;
1596 if(elec_idle_pattern_bit == 0)
1597 {
1598 transmitted_1xelec_idle = true;
1599 }
1600 }
1601 /// Send previous patterns (if any) with link and lane #s non pad
1602 else if(ts1_non_pad_lane_bit != 0)
1603 {
1604 for(i=0;i<LINK_WIDTH;i++)
1605 {
1606 if(LINK_WIDTH == 1)
1607 out_reg = (ts1_link_lane_non_PAD[i].range(ts1_non_pad_lane_bit,ts1_non_pad_lane_bit));
1608 else
1609 out_reg = (ts1_link_lane_non_PAD[i].range(ts1_non_pad_lane_bit,ts1_non_pad_lane_bit),out_reg.range(LINK_WIDTH-1,1));
1610 out_reg_bar = ~out_reg;
1611 }
1612 if(ts1_non_pad_lane_bit == 0)
1613 scrambler_i->scramble_descramble_all(K28_5,1,1);
1614 else if((ts1_non_pad_lane_bit %10) == 0)
1615 {
1616 for(int lane_scram = 0;lane_scram < LINK_WIDTH; lane_scram++)
1617 {
1618 scrambler_i->start_scramble_reg[lane_scram] = true;
1619 scrambler_i->scramble_descramble(0x00,1,0,lane_scram); // Move forward the LFSR
1620 }
1621 }
1622
1623 ts1_non_pad_lane_bit += 1;
1624 ts1_non_pad_lane_bit %= 160;
1625 }
1626 else if(ts1_non_pad_diff_lane_bit != 0)
1627 {
1628 for(i=0;i<LINK_WIDTH;i++)
1629 {
1630 if(LINK_WIDTH == 1)
1631 out_reg = (ts1_link_lane_non_PAD[i].range(ts1_non_pad_diff_lane_bit,ts1_non_pad_diff_lane_bit));
1632 else
1633 out_reg = (ts1_link_lane_non_PAD[i].range(ts1_non_pad_diff_lane_bit,ts1_non_pad_diff_lane_bit),out_reg.range(LINK_WIDTH-1,1));
1634 out_reg_bar = ~out_reg;
1635 }
1636 if(ts1_non_pad_diff_lane_bit == 0)
1637 scrambler_i->scramble_descramble_all(K28_5,1,1);
1638 else if((ts1_non_pad_diff_lane_bit %10) == 0)
1639 {
1640 for(int lane_scram = 0;lane_scram < LINK_WIDTH; lane_scram++)
1641 {
1642 scrambler_i->start_scramble_reg[lane_scram] = true;
1643 scrambler_i->scramble_descramble(0x00,1,0,lane_scram); // Move forward the LFSR
1644 }
1645 }
1646
1647 ts1_non_pad_diff_lane_bit += 1;
1648 ts1_non_pad_diff_lane_bit %= 160;
1649 }
1650 /// Send off remaining disabled patterns
1651 else if(ts1_disabled_bit != 0)
1652 {
1653 for(i=0;i<LINK_WIDTH;i++)
1654 {
1655 if(LINK_WIDTH == 1)
1656 out_reg = (disabled_set[i].range(ts1_disabled_bit,ts1_disabled_bit));
1657 else
1658 out_reg = (disabled_set[i].range(ts1_disabled_bit,ts1_disabled_bit),out_reg.range(LINK_WIDTH-1,1));
1659 out_reg_bar = ~out_reg;
1660 }
1661 if(ts1_disabled_bit == 0) // COM
1662 scrambler_i->scramble_descramble_all(K28_5,1,1);
1663 else if((ts1_disabled_bit % 10) == 0)
1664 {
1665 for(int lane_scram = 0;lane_scram < LINK_WIDTH; lane_scram++)
1666 {
1667 scrambler_i->start_scramble_reg[lane_scram] = true;
1668 scrambler_i->scramble_descramble(0x00,1,0,lane_scram); // Move forward the LFSR
1669 }
1670 }
1671 ts1_disabled_bit += 1;
1672 ts1_disabled_bit %= 160;
1673 }
1674 /// Send the remaining TS1 patterns with link and lane # set to PAD
1675 else if(ts1_pattern_bit != 0)
1676 {
1677 for(i=0;i<LINK_WIDTH;i++) // First Pattern will yield positive disparity. Resync the frame boundary here
1678 {
1679 if(LINK_WIDTH == 1)
1680 out_reg = (ts1_set_const[i].range(ts1_pattern_bit,ts1_pattern_bit));
1681 else
1682 out_reg = (ts1_set_const[i].range(ts1_pattern_bit,ts1_pattern_bit),out_reg.range(LINK_WIDTH-1,1));
1683 out_reg_bar = ~out_reg;
1684 }
1685 if(ts1_pattern_bit == 0) // COM
1686 {
1687 scrambler_i->scramble_descramble_all(K28_5,1,1);
1688 }
1689 else if((ts1_pattern_bit % 10) == 0)
1690 {
1691 for(int lane_scram = 0;lane_scram < LINK_WIDTH; lane_scram++)
1692 {
1693 scrambler_i->start_scramble_reg[lane_scram] = true;
1694 scrambler_i->scramble_descramble(0x00,1,0,lane_scram); // Move forward the LFSR
1695 }
1696
1697 }
1698 ts1_pattern_bit += 1;
1699 ts1_pattern_bit %= 160;
1700 if(ts1_pattern_bit == 0) // TS1 pattern transmitted
1701 {
1702 transmit_ts1_count--;
1703 transmitted_ts1_pattern += 1;
1704 if(transmit_ts1_count == 0)
1705 {
1706 transmitted_1024xts1_2sets = 1;
1707 transmit_ts1_count+= 17;
1708 }
1709 }
1710 }
1711 /// Send the remaining TS2 patterns with link and lane # set to PAD
1712 else if(ts2_pattern_bit != 0)
1713 {
1714 for(i=0;i<LINK_WIDTH;i++)
1715 {
1716 if(LINK_WIDTH == 1)
1717 out_reg = (ts2_set_const[i].range(ts2_pattern_bit,ts2_pattern_bit));
1718 else
1719 out_reg = (ts2_set_const[i].range(ts2_pattern_bit,ts2_pattern_bit),out_reg.range(LINK_WIDTH-1,1));
1720 out_reg_bar = ~out_reg;
1721 }
1722 if(ts2_pattern_bit == 0) // COM
1723 scrambler_i->scramble_descramble_all(K28_5,1,1);
1724 else if((ts2_pattern_bit % 10) == 0)
1725 {
1726 for(int lane_scram = 0;lane_scram < LINK_WIDTH; lane_scram++)
1727 {
1728 scrambler_i->start_scramble_reg[lane_scram] = true;
1729 scrambler_i->scramble_descramble(0x00,1,0,lane_scram); // Move forward the LFSR
1730 }
1731
1732 }
1733 ts2_pattern_bit += 1;
1734 ts2_pattern_bit %= 160;
1735 if(ts2_pattern_bit == 0)
1736 {
1737 transmit_ts2_count--;
1738 transmitted_ts2_pattern += 1;
1739 if(transmit_ts2_count == 0)
1740 transmitted_16xts2_sets = 1;
1741 }
1742 }
1743 else if(ts2_failover_pattern_bit != 0)
1744 {
1745 for(i=0;i<LINK_WIDTH;i++) // First Pattern will yield positive disparity
1746 {
1747 if(LINK_WIDTH == 1)
1748 out_reg = (ts2_set_const[i].range(ts2_failover_pattern_bit,ts2_failover_pattern_bit));
1749 else
1750 out_reg = (ts2_set_const[i].range(ts2_failover_pattern_bit,ts2_failover_pattern_bit),out_reg.range(LINK_WIDTH-1,1));
1751 out_reg_bar = ~out_reg;
1752 }
1753 if(ts2_failover_pattern_bit == 0) // COM
1754 {
1755 scrambler_i->scramble_descramble_all(K28_5,1,1);
1756 }
1757 else if((ts2_failover_pattern_bit % 10) == 0)
1758 {
1759 for(int lane_scram = 0;lane_scram < LINK_WIDTH; lane_scram++)
1760 {
1761 scrambler_i->start_scramble_reg[lane_scram] = true;
1762 scrambler_i->scramble_descramble(0x00,1,0,lane_scram); // Move forward the LFSR
1763 }
1764 }
1765 ts2_failover_pattern_bit += 1;
1766 ts2_failover_pattern_bit %= 160;
1767 if(ts2_failover_pattern_bit == 0) // TS1 pattern transmitted
1768 {
1769 transmit_failover_ts2_count--;
1770 transmitted_ts2_pattern += 1;
1771 }
1772 }
1773 /// Send the remaining TS1 patterns with link # set to non PAD
1774 else if(ts1_non_pad_link_bit != 0)
1775 {
1776 for(i=0;i<LINK_WIDTH;i++)
1777 {
1778 if(LINK_WIDTH == 1)
1779 out_reg = (ts1_link_num_non_PAD[i].range(ts1_non_pad_link_bit,ts1_non_pad_link_bit));
1780 else
1781 out_reg = (ts1_link_num_non_PAD[i].range(ts1_non_pad_link_bit,ts1_non_pad_link_bit),out_reg.range(LINK_WIDTH-1,1));
1782 out_reg_bar = ~out_reg;
1783 }
1784 if(ts1_non_pad_link_bit == 0)
1785 scrambler_i->scramble_descramble_all(K28_5,1,1);
1786 else if((ts1_non_pad_link_bit % 10) == 0)
1787 {
1788 for(int lane_scram = 0;lane_scram < LINK_WIDTH; lane_scram++)
1789 {
1790 scrambler_i->start_scramble_reg[lane_scram] = true;
1791 scrambler_i->scramble_descramble(0x00,1,0,lane_scram); // Move forward the LFSR
1792 }
1793 }
1794
1795 ts1_non_pad_link_bit += 1;
1796 ts1_non_pad_link_bit %= 160;
1797 }
1798 /// Send the remaining TS1 patterns with both link and lane # set to non PAD
1799 else if(ts1_non_pad_link_lane != 0)
1800 {
1801 for(i=0;i<LINK_WIDTH;i++)
1802 {
1803 if(LINK_WIDTH == 1)
1804 out_reg = (ts1_link_lane_non_PAD[i].range(ts1_non_pad_link_lane,ts1_non_pad_link_lane));
1805 else
1806 out_reg = (ts1_link_lane_non_PAD[i].range(ts1_non_pad_link_lane,ts1_non_pad_link_lane),out_reg.range(LINK_WIDTH-1,1));
1807 out_reg_bar = ~out_reg;
1808 }
1809 if(ts1_non_pad_link_lane == 0)
1810 scrambler_i->scramble_descramble_all(K28_5,1,1);
1811 else if((ts1_non_pad_link_lane % 10) == 0)
1812 {
1813 for(int lane_scram = 0;lane_scram < LINK_WIDTH; lane_scram++)
1814 {
1815 scrambler_i->start_scramble_reg[lane_scram] = true;
1816 scrambler_i->scramble_descramble(0x00,1,0,lane_scram); // Move forward the LFSR
1817 }
1818 }
1819
1820 ts1_non_pad_link_lane += 1;
1821 ts1_non_pad_link_lane %= 160;
1822 }
1823 else if(symbol_num != 0)
1824 {
1825 for(i=0;i<LINK_WIDTH;i++)
1826 {
1827 if(LINK_WIDTH == 1)
1828 out_reg = (ts2_link_lane_non_PAD[i].range(symbol_num,symbol_num));
1829 else
1830 out_reg = (ts2_link_lane_non_PAD[i].range(symbol_num,symbol_num),out_reg.range(LINK_WIDTH-1,1));
1831 out_reg_bar = ~out_reg;
1832 }
1833 if(symbol_num == 0)
1834 {
1835 scrambler_i->scramble_descramble_all(K28_5,1,1);
1836 }
1837 else if((symbol_num % 10) == 0)
1838 {
1839 for(int lane_scram = 0;lane_scram < LINK_WIDTH; lane_scram++)
1840 {
1841 scrambler_i->start_scramble_reg[lane_scram] = true;
1842 scrambler_i->scramble_descramble(0x00,1,0,lane_scram); // Move forward the LFSR
1843 }
1844 }
1845
1846 symbol_num++;
1847 symbol_num %= 160;
1848 if(symbol_num == 0)
1849 {
1850 transmit_ts2_count--;
1851 transmitted_ts2_pattern += 1;
1852
1853 if(transmit_ts2_count == 0)
1854 transmitted_16xts2_sets = 1;
1855 }
1856 }
1857 /// Send the remaining Logical Idle patterns
1858 else if(idle_pattern_bit != 0)
1859 {
1860 for(i=0;i<LINK_WIDTH;i++)
1861 {
1862 if(LINK_WIDTH == 1)
1863 out_reg = (idle_set_const[i].range(idle_pattern_bit,idle_pattern_bit));
1864 else
1865 out_reg = (idle_set_const[i].range(idle_pattern_bit,idle_pattern_bit),out_reg.range(LINK_WIDTH-1,1));
1866 out_reg_bar = ~out_reg;
1867 }
1868 idle_pattern_bit += 1;
1869 idle_pattern_bit %= 10;
1870 if(idle_pattern_bit == 0)
1871 {
1872 transmit_idl_count--;
1873 transmitted_idl_pattern += 1;
1874
1875 if(transmit_idl_count == 0)
1876 transmitted_16xidl_sets = 1;
1877 if(init_done.read()) done_last_idle++;
1878 }
1879 }
1880 prev_init_state = DETECT_QUIET;
1881 }
1882
1883 if(received_1xts2_sets && init_state == POLLING_CONFIG) // Transmit buffers for POLLING_CONFIG
1884 {
1885 // What if the state has not yet changed. but transmit_ts2_count is 0
1886 // Transmit one more
1887 if(transmitted_16xts2_sets)
1888 transmit_ts2_count = 1; // Transmit the last one
1889 if ( transmit_ts2_count != 0 )
1890 {
1891 // Transmission based on calculation of CRD
1892 if(ts2_pattern_bit == 0 && ts1_pattern_bit == 0 && ts2_failover_pattern_bit == 0)
1893 {
1894 for(i=0;i<LINK_WIDTH;i++)
1895 {
1896 if(curr_running_disp->get_CRD(i).to_bool())
1897 {
1898 iter = map_table->spec_symbol_map.find(K28_5);
1899 ts2_set_const[i].range(0,9) = iter->second;
1900 set_delim_value(TS2_SET_CONST,i);
1901 }
1902 else if(!curr_running_disp->get_CRD(i).to_bool())
1903 {
1904 iter = map_table->spec_symbol_map.find(K28_5);
1905 ts2_set_const[i].range(0,9) = ~(iter->second);
1906 set_delim_value(TS2_SET_CONST,i);
1907 }
1908 if(curr_running_disp->calculate_disparity(ts2_set_const[i].range(0,9),0) == 1)
1909 {
1910 curr_running_disp->set_CRD(i,sc_logic(1));
1911 }
1912 else if(curr_running_disp->calculate_disparity(ts2_set_const[i].range(0,9),0) == 0)
1913 {
1914 curr_running_disp->set_CRD(i,sc_logic(0));
1915 }
1916 }
1917
1918 for(i=0;i<LINK_WIDTH;i++)
1919 {
1920 if(curr_running_disp->get_CRD(i).to_bool())
1921 {
1922 iter = map_table->spec_symbol_map.find(K23_7);
1923 ts2_set_const[i].range(10,19) = iter->second; // Neutral disparity
1924 iter = map_table->spec_symbol_map.find(K23_7);
1925 ts2_set_const[i].range(20,29) = iter->second; // Neutral
1926 ts2_set_const[i].range(30,39) = 0x15a; // Neutral
1927 iter = map_table->data_encode_map.find(D2_0);
1928 ts2_set_const[i].range(40,49) = iter->second; // Neutral
1929 iter = map_table->data_encode_map.find(D0_0);
1930 ts2_set_const[i].range(50,59) = iter->second; // Neutral
1931 }
1932 else if(!curr_running_disp->get_CRD(i).to_bool())
1933 {
1934 iter = map_table->spec_symbol_map.find(K23_7);
1935 ts2_set_const[i].range(10,19) = ~(iter->second); // Neutral disparity
1936 iter = map_table->spec_symbol_map.find(K23_7);
1937 ts2_set_const[i].range(20,29) = ~(iter->second); // Neutral
1938 ts2_set_const[i].range(30,39) = TS2_DELIM; // Neutral
1939 iter = map_table->neg_data_encode_map.find(D2_0);
1940 ts2_set_const[i].range(40,49) = (iter->second); // Neutral
1941 iter = map_table->neg_data_encode_map.find(D0_0);
1942 ts2_set_const[i].range(50,59) = (iter->second); // Neutral
1943 }
1944 }
1945 }
1946
1947 /// Go ahead with the transmission of POLLING_CONFIG ordered set
1948 if(ts1_pattern_bit == 0 && ts2_failover_pattern_bit == 0)
1949 {
1950 for(i=0;i<LINK_WIDTH;i++)
1951 {
1952 if(LINK_WIDTH == 1)
1953 out_reg = (ts2_set_const[i].range(ts2_pattern_bit,ts2_pattern_bit));
1954 else
1955 out_reg = (ts2_set_const[i].range(ts2_pattern_bit,ts2_pattern_bit),out_reg.range(LINK_WIDTH-1,1));
1956 out_reg_bar = ~out_reg;
1957 }
1958 if(ts2_pattern_bit == 0) // COM
1959 scrambler_i->scramble_descramble_all(K28_5,1,1);
1960 else if((ts2_pattern_bit % 10) == 0)
1961 {
1962 for(int lane_scram = 0;lane_scram < LINK_WIDTH; lane_scram++)
1963 {
1964 scrambler_i->start_scramble_reg[lane_scram] = true;
1965 scrambler_i->scramble_descramble(0x00,1,0,lane_scram); // Move forward the LFSR
1966 }
1967 }
1968 ts2_pattern_bit += 1;
1969 ts2_pattern_bit %= 160;
1970 if(ts2_pattern_bit == 0)
1971 {
1972 transmit_ts2_count--;
1973 transmitted_ts2_pattern += 1;
1974 if(transmit_ts2_count == 0)
1975 transmitted_16xts2_sets = 1;
1976 }
1977 }
1978 else if(ts1_pattern_bit != 0)// Complete the previous transaction of TS1 OS
1979 {
1980 for(i=0;i<LINK_WIDTH;i++)
1981 {
1982 if(LINK_WIDTH == 1)
1983 out_reg = (ts1_set_const[i].range(ts1_pattern_bit,ts1_pattern_bit));
1984 else
1985 out_reg = (ts1_set_const[i].range(ts1_pattern_bit,ts1_pattern_bit),out_reg.range(LINK_WIDTH-1,1));
1986 out_reg_bar = ~out_reg;
1987 }
1988 if(ts1_pattern_bit == 0)
1989 scrambler_i->scramble_descramble_all(K28_5,1,1);
1990 else if((ts1_pattern_bit % 10) == 0)
1991 {
1992 for(int lane_scram = 0;lane_scram < LINK_WIDTH; lane_scram++)
1993 {
1994 scrambler_i->start_scramble_reg[lane_scram] = true;
1995 scrambler_i->scramble_descramble(0x00,1,0,lane_scram); // Move forward the LFSR
1996 }
1997 }
1998 ts1_pattern_bit++;
1999 ts1_pattern_bit %= 160;
2000 }
2001 else if(ts2_failover_pattern_bit != 0)
2002 {
2003 for(i=0;i<LINK_WIDTH;i++) // First Pattern will yield positive disparity
2004 {
2005 if(LINK_WIDTH == 1)
2006 out_reg = (ts2_set_const[i].range(ts2_failover_pattern_bit,ts2_failover_pattern_bit));
2007 else
2008 out_reg = (ts2_set_const[i].range(ts2_failover_pattern_bit,ts2_failover_pattern_bit),out_reg.range(LINK_WIDTH-1,1));
2009 out_reg_bar = ~out_reg;
2010 }
2011 if(ts2_failover_pattern_bit == 0) // COM
2012 {
2013 scrambler_i->scramble_descramble_all(K28_5,1,1);
2014 }
2015 else if((ts2_failover_pattern_bit % 10) == 0)
2016 {
2017 for(int lane_scram = 0;lane_scram < LINK_WIDTH; lane_scram++)
2018 {
2019 scrambler_i->start_scramble_reg[lane_scram] = true;
2020 scrambler_i->scramble_descramble(0x00,1,0,lane_scram); // Move forward the LFSR
2021 }
2022 }
2023 ts2_failover_pattern_bit += 1;
2024 ts2_failover_pattern_bit %= 160;
2025 if(ts2_failover_pattern_bit == 0) // TS1 pattern transmitted
2026 {
2027 transmit_failover_ts2_count--;
2028 transmitted_ts2_pattern += 1;
2029 }
2030 }
2031 }
2032 else // stop transmit
2033 {
2034 transmitted_16xts2_sets = 1;
2035 received_8xts2_sets =0;
2036 }
2037 prev_init_state = POLLING_CONFIG;
2038 }
2039 if(!received_1xts2_sets && init_state == POLLING_CONFIG) // POLLING_CONFIG reached but still not received any TS2. Start transmitting TS2
2040 {
2041 if(transmit_failover_ts2_count != 0)
2042 {
2043 if(ts2_failover_pattern_bit == 0 && ts2_pattern_bit == 0 && ts1_pattern_bit == 0)
2044 {
2045 for(i=0;i<LINK_WIDTH;i++)
2046 {
2047 if(curr_running_disp->get_CRD(i).to_bool())
2048 {
2049 iter = map_table->spec_symbol_map.find(K28_5);
2050 ts2_set_const[i].range(0,9) = iter->second;
2051 set_delim_value(TS2_SET_CONST,i);
2052 }
2053 else if(!curr_running_disp->get_CRD(i).to_bool())
2054 {
2055 iter = map_table->spec_symbol_map.find(K28_5);
2056 ts2_set_const[i].range(0,9) = ~(iter->second);
2057 set_delim_value(TS2_SET_CONST,i);
2058 }
2059 if(curr_running_disp->calculate_disparity(ts2_set_const[i].range(0,9),0) == 1)
2060 {
2061 curr_running_disp->set_CRD(i,sc_logic(1));
2062 }
2063 else if(curr_running_disp->calculate_disparity(ts2_set_const[i].range(0,9),0) == 0)
2064 {
2065 curr_running_disp->set_CRD(i,sc_logic(0));
2066 }
2067 }
2068 for(i=0;i<LINK_WIDTH;i++)
2069 {
2070 if(curr_running_disp->get_CRD(i).to_bool())
2071 {
2072 iter = map_table->spec_symbol_map.find(K23_7);
2073 ts2_set_const[i].range(10,19) = iter->second; // Neutral disparity
2074 iter = map_table->spec_symbol_map.find(K23_7);
2075 ts2_set_const[i].range(20,29) = iter->second; // Neutral
2076 ts2_set_const[i].range(30,39) = 0x15a; // Neutral
2077 iter = map_table->data_encode_map.find(D2_0);
2078 ts2_set_const[i].range(40,49) = iter->second; // Neutral
2079 iter = map_table->data_encode_map.find(D0_0);
2080 ts2_set_const[i].range(50,59) = iter->second; // Neutral
2081 }
2082 else if(!curr_running_disp->get_CRD(i).to_bool())
2083 {
2084 iter = map_table->spec_symbol_map.find(K23_7);
2085 ts2_set_const[i].range(10,19) = ~(iter->second); // Neutral disparity
2086 iter = map_table->spec_symbol_map.find(K23_7);
2087 ts2_set_const[i].range(20,29) = ~(iter->second); // Neutral
2088 ts2_set_const[i].range(30,39) = TS2_DELIM; // Neutral
2089 iter = map_table->neg_data_encode_map.find(D2_0);
2090 ts2_set_const[i].range(40,49) = (iter->second); // Neutral
2091 iter = map_table->neg_data_encode_map.find(D0_0);
2092 ts2_set_const[i].range(50,59) = (iter->second); // Neutral
2093 }
2094 }
2095 }
2096
2097 /// Go ahead with the transmission of POLLING_CONFIG patterns
2098 if(ts1_pattern_bit == 0 && ts2_pattern_bit == 0)
2099 {
2100 for(i=0;i<LINK_WIDTH;i++) // First Pattern will yield positive disparity
2101 {
2102 if(LINK_WIDTH == 1)
2103 out_reg = (ts2_set_const[i].range(ts2_failover_pattern_bit,ts2_failover_pattern_bit));
2104 else
2105 out_reg = (ts2_set_const[i].range(ts2_failover_pattern_bit,ts2_failover_pattern_bit),out_reg.range(LINK_WIDTH-1,1));
2106 out_reg_bar = ~out_reg;
2107 }
2108 if(ts2_failover_pattern_bit == 0) // COM
2109 {
2110 scrambler_i->scramble_descramble_all(K28_5,1,1);
2111 }
2112 else if((ts2_failover_pattern_bit % 10) == 0)
2113 {
2114 for(int lane_scram = 0;lane_scram < LINK_WIDTH; lane_scram++)
2115 {
2116 scrambler_i->start_scramble_reg[lane_scram] = true;
2117 scrambler_i->scramble_descramble(0x00,1,0,lane_scram); // Move forward the LFSR
2118 }
2119 }
2120 ts2_failover_pattern_bit += 1;
2121 ts2_failover_pattern_bit %= 160;
2122 if(ts2_failover_pattern_bit == 0) // TS1 pattern transmitted
2123 {
2124 transmit_failover_ts2_count--;
2125 transmitted_ts2_pattern += 1;
2126 }
2127 }
2128 else // Complete the previous transaction of TS1 OS
2129 {
2130 for(i=0;i<LINK_WIDTH;i++)
2131 {
2132 if(LINK_WIDTH == 1)
2133 out_reg = (ts1_set_const[i].range(ts1_pattern_bit,ts1_pattern_bit));
2134 else
2135 out_reg = (ts1_set_const[i].range(ts1_pattern_bit,ts1_pattern_bit),out_reg.range(LINK_WIDTH-1,1));
2136 out_reg_bar = ~out_reg;
2137 }
2138 if(ts1_pattern_bit == 0)
2139 scrambler_i->scramble_descramble_all(K28_5,1,1);
2140 else if((ts1_pattern_bit % 10) == 0)
2141 {
2142 for(int lane_scram = 0;lane_scram < LINK_WIDTH; lane_scram++)
2143 {
2144 scrambler_i->start_scramble_reg[lane_scram] = true;
2145 scrambler_i->scramble_descramble(0x00,1,0,lane_scram); // Move forward the LFSR
2146 }
2147 }
2148 ts1_pattern_bit++;
2149 ts1_pattern_bit %= 160;
2150 }
2151
2152 }
2153 prev_init_state = POLLING_CONFIG;
2154 }
2155 if (((received_1xts1_sets || received_1xts2_sets || enter_drain_state) && init_state == POLLING_ACTIVE)) { // Transmit buffers for POLLING_ACTIVE
2156 transmit_failover_ts2_count = 300;
2157 if(enter_drain_state)
2158 {
2159 out_reg = 0x00;
2160 out_reg_bar = ~out_reg;
2161 }
2162 if(transmit_ts1_count != 0)
2163 {
2164 if(ts1_pattern_bit == 0 && elec_idle_pattern_bit == 0 && ts1_non_pad_lane_bit == 0 && symbol_num == 0) // Additional checks for Recovery_RcvrLock
2165 {
2166 for(i=0;i<LINK_WIDTH;i++)
2167 {
2168 if(curr_running_disp->get_CRD(i).to_bool())
2169 {
2170 iter = map_table->spec_symbol_map.find(K28_5);
2171 ts1_set_const[i].range(0,9) = iter->second;
2172 set_delim_value(TS1_SET_CONST,i);
2173 }
2174 else if(!curr_running_disp->get_CRD(i).to_bool())
2175 {
2176 iter = map_table->spec_symbol_map.find(K28_5);
2177 ts1_set_const[i].range(0,9) = ~(iter->second);
2178 set_delim_value(TS1_SET_CONST,i);
2179 }
2180 if(curr_running_disp->calculate_disparity(ts1_set_const[i].range(0,9),0) == 1)
2181 {
2182 curr_running_disp->set_CRD(i,sc_logic(1));
2183 }
2184 else if(curr_running_disp->calculate_disparity(ts1_set_const[i].range(0,9),0) == 0)
2185 {
2186 curr_running_disp->set_CRD(i,sc_logic(0));
2187 }
2188 }
2189 for(i=0;i<LINK_WIDTH;i++)
2190 {
2191 if(curr_running_disp->get_CRD(i).to_bool())
2192 {
2193 iter = map_table->spec_symbol_map.find(K23_7);
2194 ts1_set_const[i].range(10,19) = iter->second; // Neutral disparity
2195 iter = map_table->spec_symbol_map.find(K23_7);
2196 ts1_set_const[i].range(20,29) = iter->second; // Neutral
2197 ts1_set_const[i].range(30,39) = 0x15a; // Neutral
2198 iter = map_table->data_encode_map.find(D2_0);
2199 ts1_set_const[i].range(40,49) = iter->second; // Neutral
2200 iter = map_table->data_encode_map.find(D0_0);
2201 ts1_set_const[i].range(50,59) = iter->second; // Neutral
2202 }
2203 else if(!curr_running_disp->get_CRD(i).to_bool())
2204 {
2205 iter = map_table->spec_symbol_map.find(K23_7);
2206 ts1_set_const[i].range(10,19) = ~(iter->second); // Neutral disparity
2207 iter = map_table->spec_symbol_map.find(K23_7);
2208 ts1_set_const[i].range(20,29) = ~(iter->second); // Neutral
2209 ts1_set_const[i].range(30,39) = TS2_DELIM; // Neutral
2210 iter = map_table->neg_data_encode_map.find(D2_0);
2211 ts1_set_const[i].range(40,49) = (iter->second); // Neutral
2212 iter = map_table->neg_data_encode_map.find(D0_0);
2213 ts1_set_const[i].range(50,59) = (iter->second); // Neutral
2214 }
2215 }
2216 }
2217
2218 /// Go ahead with the transmission of the POLLING_ACTIVE patterns
2219 if(elec_idle_pattern_bit == 0 && ts1_non_pad_lane_bit == 0 && symbol_num == 0)
2220 {
2221
2222 for(i=0;i<LINK_WIDTH;i++) // First Pattern will yield positive disparity. Resync the frame boundary here
2223 {
2224 if(LINK_WIDTH == 1)
2225 out_reg = (ts1_set_const[i].range(ts1_pattern_bit,ts1_pattern_bit));
2226 else
2227 out_reg = (ts1_set_const[i].range(ts1_pattern_bit,ts1_pattern_bit),out_reg.range(LINK_WIDTH-1,1));
2228 out_reg_bar = ~out_reg;
2229 }
2230 if(ts1_pattern_bit == 0) // COM
2231 {
2232 scrambler_i->scramble_descramble_all(K28_5,1,1);
2233 }
2234 else if((ts1_pattern_bit % 10) == 0)
2235 {
2236 for(int lane_scram = 0;lane_scram < LINK_WIDTH; lane_scram++)
2237 {
2238 scrambler_i->start_scramble_reg[lane_scram] = true;
2239 scrambler_i->scramble_descramble(0x00,1,0,lane_scram); // Move forward the LFSR
2240 }
2241 }
2242 ts1_pattern_bit += 1;
2243 ts1_pattern_bit %= 160;
2244 if(ts1_pattern_bit == 0) // TS1 pattern transmitted
2245 {
2246 transmit_ts1_count--;
2247 transmitted_ts1_pattern += 1;
2248 if(transmit_ts1_count == 0)
2249 {
2250 transmitted_1024xts1_2sets = 1;
2251 transmit_ts1_count+= 17;
2252 }
2253 }
2254 }
2255
2256 /// Complete previous patterns if any
2257 else if(ts1_non_pad_lane_bit == 0 && elec_idle_pattern_bit != 0)
2258 {
2259 for(i=0;i<LINK_WIDTH;i++)
2260 {
2261 if(LINK_WIDTH == 1)
2262 out_reg = (elec_idle_set[i].range(elec_idle_pattern_bit,elec_idle_pattern_bit));
2263 else
2264 out_reg = (elec_idle_set[i].range(elec_idle_pattern_bit,elec_idle_pattern_bit),out_reg.range(LINK_WIDTH-1,1));
2265 out_reg_bar = ~out_reg;
2266 }
2267 if(elec_idle_pattern_bit == 0)
2268 scrambler_i->scramble_descramble_all(K28_5,1,1);
2269 else if((elec_idle_pattern_bit % 10) == 0)
2270 {
2271 for(int lane_scram = 0;lane_scram < LINK_WIDTH; lane_scram++)
2272 {
2273 scrambler_i->start_scramble_reg[lane_scram] = true;
2274 scrambler_i->scramble_descramble(0x00,1,0,lane_scram); // Move forward the LFSR
2275 }
2276 }
2277 elec_idle_pattern_bit++;
2278 elec_idle_pattern_bit %= 40;
2279 }
2280
2281 /// Complete previous patterns (if any) for TS2 OS with non PAD link and lane #
2282 else if(symbol_num != 0)
2283 {
2284 for(i=0;i<LINK_WIDTH;i++)
2285 {
2286 if(LINK_WIDTH == 1)
2287 out_reg = (ts2_link_lane_non_PAD[i].range(symbol_num,symbol_num));
2288 else
2289 out_reg = (ts2_link_lane_non_PAD[i].range(symbol_num,symbol_num),out_reg.range(LINK_WIDTH-1,1));
2290 out_reg_bar = ~out_reg;
2291 }
2292 if(symbol_num == 0)
2293 {
2294 scrambler_i->scramble_descramble_all(K28_5,1,1);
2295 }
2296 else if((symbol_num % 10) == 0)
2297 {
2298 for(int lane_scram = 0;lane_scram < LINK_WIDTH; lane_scram++)
2299 {
2300 scrambler_i->start_scramble_reg[lane_scram] = true;
2301 scrambler_i->scramble_descramble(0x00,1,0,lane_scram); // Move forward the LFSR
2302 }
2303 }
2304
2305 symbol_num++;
2306 symbol_num %= 160;
2307 if(symbol_num == 0)
2308 {
2309 if(transmit_ts2_count > 0) transmit_ts2_count--;
2310 transmitted_ts2_pattern += 1;
2311
2312 if(transmit_ts2_count == 0)
2313 transmitted_16xts2_sets = 1;
2314 }
2315 }
2316 else
2317 {
2318 for(i=0;i<LINK_WIDTH;i++)
2319 {
2320 if(LINK_WIDTH == 1)
2321 out_reg = (ts1_link_lane_non_PAD[i].range(ts1_non_pad_lane_bit,ts1_non_pad_lane_bit));
2322 else
2323 out_reg = (ts1_link_lane_non_PAD[i].range(ts1_non_pad_lane_bit,ts1_non_pad_lane_bit),out_reg.range(LINK_WIDTH-1,1));
2324 out_reg_bar = ~out_reg;
2325 }
2326 if(ts1_non_pad_lane_bit == 0)
2327 scrambler_i->scramble_descramble_all(K28_5,1,1);
2328 else if((ts1_non_pad_lane_bit %10) == 0)
2329 {
2330 for(int lane_scram = 0;lane_scram < LINK_WIDTH; lane_scram++)
2331 {
2332 scrambler_i->start_scramble_reg[lane_scram] = true;
2333 scrambler_i->scramble_descramble(0x00,1,0,lane_scram); // Move forward the LFSR
2334 }
2335 }
2336
2337 ts1_non_pad_lane_bit += 1;
2338 ts1_non_pad_lane_bit %= 160;
2339 }
2340 }
2341 else
2342 {
2343 transmitted_1024xts1_2sets = 1;
2344 received_8xts1_sets = 0;
2345 }
2346 prev_init_state = POLLING_ACTIVE;
2347 }
2348
2349 /// POLLING_ACTIVE, but not yet received any ts2 OS
2350 else if(!received_1xts2_sets && !received_1xts1_sets && init_state == POLLING_ACTIVE) // Complete the transaction from Recovery?
2351 {
2352 if(ts1_non_pad_lane_bit != 0)
2353 {
2354 for(i=0;i<LINK_WIDTH;i++)
2355 {
2356 if(LINK_WIDTH == 1)
2357 out_reg = (ts1_link_lane_non_PAD[i].range(ts1_non_pad_lane_bit,ts1_non_pad_lane_bit));
2358 else
2359 out_reg = (ts1_link_lane_non_PAD[i].range(ts1_non_pad_lane_bit,ts1_non_pad_lane_bit),out_reg.range(LINK_WIDTH-1,1));
2360 out_reg_bar = ~out_reg;
2361 }
2362 if(ts1_non_pad_lane_bit == 0)
2363 scrambler_i->scramble_descramble_all(K28_5,1,1);
2364 else if((ts1_non_pad_lane_bit %10) == 0)
2365 {
2366 for(int lane_scram = 0;lane_scram < LINK_WIDTH; lane_scram++)
2367 {
2368 scrambler_i->start_scramble_reg[lane_scram] = true;
2369 scrambler_i->scramble_descramble(0x00,1,0,lane_scram); // Move forward the LFSR
2370 }
2371 }
2372
2373 ts1_non_pad_lane_bit += 1;
2374 ts1_non_pad_lane_bit %= 160;
2375 }
2376 else if(symbol_num != 0)
2377 {
2378 for(i=0;i<LINK_WIDTH;i++)
2379 {
2380 if(LINK_WIDTH == 1)
2381 out_reg = (ts2_link_lane_non_PAD[i].range(symbol_num,symbol_num));
2382 else
2383 out_reg = (ts2_link_lane_non_PAD[i].range(symbol_num,symbol_num),out_reg.range(LINK_WIDTH-1,1));
2384 out_reg_bar = ~out_reg;
2385 }
2386 if(symbol_num == 0)
2387 {
2388
2389 scrambler_i->scramble_descramble_all(K28_5,1,1);
2390 }
2391 else if((symbol_num % 10) == 0)
2392 {
2393 for(int lane_scram = 0;lane_scram < LINK_WIDTH; lane_scram++)
2394 {
2395 scrambler_i->start_scramble_reg[lane_scram] = true;
2396 scrambler_i->scramble_descramble(0x00,1,0,lane_scram); // Move forward the LFSR
2397 }
2398 }
2399
2400 symbol_num++;
2401 symbol_num %= 160;
2402 if(symbol_num == 0)
2403 {
2404 if(transmit_ts2_count > 0) transmit_ts2_count--;
2405 transmitted_ts2_pattern += 1;
2406
2407 if(transmit_ts2_count == 0)
2408 transmitted_16xts2_sets = 1;
2409 }
2410 }
2411 }
2412
2413 /// init_state = CFG_LINKWIDTH_START
2414 if(init_state == CFG_LINKWIDTH_START) // Just keep sending TS1 patterns with link_num ~= PAD. Disparity is forced to be positive. name is enough
2415 {
2416 // Calculate CRD for link_num_non_PAD
2417 if(ts1_non_pad_link_bit == 0 && ts2_pattern_bit == 0 && ts1_non_pad_lane_bit == 0)
2418 {
2419 for(i=0;i<LINK_WIDTH;i++)
2420 {
2421 if(curr_running_disp->get_CRD(i).to_bool())
2422 {
2423 iter = map_table->spec_symbol_map.find(K28_5);
2424 ts1_link_num_non_PAD[i].range(0,9) = iter->second;
2425 set_delim_value(TS1_LINK_NUM_NON_PAD,i);
2426
2427 }
2428 else if(!curr_running_disp->get_CRD(i).to_bool())
2429 {
2430 iter = map_table->spec_symbol_map.find(K28_5);
2431 ts1_link_num_non_PAD[i].range(0,9) = ~(iter->second);
2432 set_delim_value(TS1_LINK_NUM_NON_PAD,i);
2433 }
2434 // Does the entire frame of COM symbols have a single disparity value?
2435 if(curr_running_disp->calculate_disparity(ts1_link_num_non_PAD[i].range(0,9),0) == 1)
2436 {
2437 curr_running_disp->set_CRD(i,sc_logic(1));
2438 }
2439 else if(curr_running_disp->calculate_disparity(ts1_link_num_non_PAD[i].range(0,9),0) == 0)
2440 {
2441 curr_running_disp->set_CRD(i,sc_logic(0));
2442 }
2443 }
2444
2445 // Calculate disparity for link #
2446 for(i=0;i<LINK_WIDTH;i++)
2447 {
2448 if(curr_running_disp->get_CRD(i).to_bool())
2449 {
2450 iter = map_table->data_encode_map.find(D0_0);
2451 ts1_link_num_non_PAD[i].range(10,19) = iter->second;
2452 }
2453 else if(!curr_running_disp->get_CRD(i).to_bool())
2454 {
2455 iter = map_table->neg_data_encode_map.find(D0_0);
2456 ts1_link_num_non_PAD[i].range(10,19) = (iter->second); // Neutral disparity
2457 }
2458 if(curr_running_disp->calculate_disparity(ts1_link_num_non_PAD[i].range(10,19),0) == 0)
2459 {
2460 // Could be equal number of 1s and 0s
2461 curr_running_disp->set_CRD(i,sc_logic(0));
2462 }
2463 else if(curr_running_disp->calculate_disparity(ts1_link_num_non_PAD[i].range(10,19),0) == 1)
2464 {
2465 curr_running_disp->set_CRD(i,sc_logic(1));
2466 }
2467 }
2468
2469 for(i=0;i<LINK_WIDTH;i++)
2470 {
2471 if(curr_running_disp->get_CRD(i).to_bool())
2472 {
2473 iter = map_table->spec_symbol_map.find(K23_7);
2474 ts1_link_num_non_PAD[i].range(20,29) = iter->second;
2475 ts1_link_num_non_PAD[i].range(30,39) = 0x15a;
2476 iter = map_table->data_encode_map.find(D2_0);
2477 ts1_link_num_non_PAD[i].range(40,49) = iter->second;
2478 if(link_ctl_csr.range(4,4) == 0x0)
2479 iter = map_table->data_encode_map.find(D0_0);
2480 else
2481 iter = map_table->data_encode_map.find(D2_0);
2482 ts1_link_num_non_PAD[i].range(50,59) = iter->second;
2483 }
2484 else if(!curr_running_disp->get_CRD(i).to_bool())
2485 {
2486 iter = map_table->spec_symbol_map.find(K23_7);
2487 ts1_link_num_non_PAD[i].range(20,29) = ~(iter->second); // Neutral
2488 ts1_link_num_non_PAD[i].range(30,39) = TS2_DELIM; // Neutral
2489 iter = map_table->neg_data_encode_map.find(D2_0);
2490 ts1_link_num_non_PAD[i].range(40,49) = (iter->second); // Neutral
2491 if(link_ctl_csr.range(4,4) == 0x0)
2492 iter = map_table->neg_data_encode_map.find(D0_0);
2493 else
2494 iter = map_table->neg_data_encode_map.find(D2_0);
2495 ts1_link_num_non_PAD[i].range(50,59) = (iter->second); // Neutral
2496 }
2497 }
2498 }
2499
2500 /// Go ahead with the transmission of current state patterns
2501 if(ts2_pattern_bit == 0 && ts1_non_pad_lane_bit == 0)
2502 {
2503 for(i=0;i<LINK_WIDTH;i++)
2504 {
2505 if(LINK_WIDTH == 1)
2506 out_reg = (ts1_link_num_non_PAD[i].range(ts1_non_pad_link_bit,ts1_non_pad_link_bit));
2507 else
2508 out_reg = (ts1_link_num_non_PAD[i].range(ts1_non_pad_link_bit,ts1_non_pad_link_bit),out_reg.range(LINK_WIDTH-1,1));
2509 out_reg_bar = ~out_reg;
2510 }
2511 if(ts1_non_pad_link_bit == 0)
2512 scrambler_i->scramble_descramble_all(K28_5,1,1);
2513 else if((ts1_non_pad_link_bit % 10) == 0)
2514 {
2515 for(int lane_scram = 0;lane_scram < LINK_WIDTH; lane_scram++)
2516 {
2517 scrambler_i->start_scramble_reg[lane_scram] = true;
2518 scrambler_i->scramble_descramble(0x00,1,0,lane_scram); // Move forward the LFSR
2519 }
2520 }
2521
2522 ts1_non_pad_link_bit += 1;
2523 ts1_non_pad_link_bit %= 160;
2524 }
2525
2526 /// Complete previous patterns if any
2527 else if(ts2_pattern_bit == 0 && ts1_non_pad_lane_bit != 0)
2528 {
2529 for(i=0;i<LINK_WIDTH;i++)
2530 {
2531 if(LINK_WIDTH == 1)
2532 out_reg = (ts1_link_lane_non_PAD[i].range(ts1_non_pad_lane_bit,ts1_non_pad_lane_bit));
2533 else
2534 out_reg = (ts1_link_lane_non_PAD[i].range(ts1_non_pad_lane_bit,ts1_non_pad_lane_bit),out_reg.range(LINK_WIDTH-1,1));
2535 out_reg_bar = ~out_reg;
2536 }
2537 if(ts1_non_pad_lane_bit == 0)
2538 scrambler_i->scramble_descramble_all(K28_5,1,1);
2539 else if((ts1_non_pad_lane_bit %10) == 0)
2540 {
2541 for(int lane_scram = 0;lane_scram < LINK_WIDTH; lane_scram++)
2542 {
2543 scrambler_i->start_scramble_reg[lane_scram] = true;
2544 scrambler_i->scramble_descramble(0x00,1,0,lane_scram); // Move forward the LFSR
2545 }
2546 }
2547 ts1_non_pad_lane_bit += 1;
2548 ts1_non_pad_lane_bit %= 160;
2549 }
2550 else
2551 {
2552 for(i=0;i<LINK_WIDTH;i++)
2553 {
2554 if(LINK_WIDTH == 1)
2555 out_reg = (ts2_set_const[i].range(ts2_pattern_bit,ts2_pattern_bit));
2556 else
2557 out_reg = (ts2_set_const[i].range(ts2_pattern_bit,ts2_pattern_bit),out_reg.range(LINK_WIDTH-1,1));
2558 out_reg_bar = ~out_reg;
2559 }
2560 if(ts2_pattern_bit == 0)
2561 scrambler_i->scramble_descramble_all(K28_5,1,1);
2562 else if((ts2_pattern_bit % 10) == 0)
2563 {
2564 for(int lane_scram = 0;lane_scram < LINK_WIDTH; lane_scram++)
2565 {
2566 scrambler_i->start_scramble_reg[lane_scram] = true;
2567 scrambler_i->scramble_descramble(0x00,1,0,lane_scram); // Move forward the LFSR
2568 }
2569 }
2570 ts2_pattern_bit += 1;
2571 ts2_pattern_bit %= 160;
2572 }
2573 }
2574
2575 /// init_state = CFG_LINKWIDTH_ACCEPT
2576 if(init_state == CFG_LINKWIDTH_ACCEPT) // Transmit buffer for CFG_LINKWIDTH_ACCEPT
2577 {
2578 // Calculate CRD for link_num_non_PAD
2579 if(ts1_non_pad_link_lane == 0 && ts1_non_pad_link_bit == 0 && ts1_non_pad_lane_bit == 0)
2580 {
2581 for(i=0;i<LINK_WIDTH;i++)
2582 {
2583 if(curr_running_disp->get_CRD(i).to_bool())
2584 {
2585 iter = map_table->spec_symbol_map.find(K28_5);
2586 ts1_link_lane_non_PAD[i].range(0,9) = iter->second;
2587 set_delim_value(TS1_LINK_LANE_NON_PAD,i);
2588 }
2589 else if(!curr_running_disp->get_CRD(i).to_bool())
2590 {
2591 iter = map_table->spec_symbol_map.find(K28_5);
2592 ts1_link_lane_non_PAD[i].range(0,9) = ~(iter->second);
2593 set_delim_value(TS1_LINK_LANE_NON_PAD,i);
2594 }
2595 if(curr_running_disp->calculate_disparity(ts1_link_lane_non_PAD[i].range(0,9),0) == 1)
2596 {
2597 curr_running_disp->set_CRD(i,sc_logic(1));
2598 }
2599 else if(curr_running_disp->calculate_disparity(ts1_link_lane_non_PAD[i].range(0,9),0) == 0)
2600 {
2601 curr_running_disp->set_CRD(i,sc_logic(0));
2602 }
2603 }
2604
2605 // Calculate disparity for link #
2606 for(i=0;i<LINK_WIDTH;i++)
2607 {
2608 if(curr_running_disp->get_CRD(i).to_bool())
2609 {
2610 iter = map_table->data_encode_map.find(D0_0);
2611 ts1_link_lane_non_PAD[i].range(10,19) = iter->second;
2612 }
2613 else if(!curr_running_disp->get_CRD(i).to_bool())
2614 {
2615 iter = map_table->neg_data_encode_map.find(D0_0);
2616 ts1_link_lane_non_PAD[i].range(10,19) = (iter->second); // Neutral disparity
2617 }
2618 if(curr_running_disp->calculate_disparity(ts1_link_lane_non_PAD[i].range(10,19),0) == 1)
2619 {
2620 curr_running_disp->set_CRD(i,sc_logic(1));
2621 }
2622 else if(curr_running_disp->calculate_disparity(ts1_link_lane_non_PAD[i].range(10,19),0) == 0)
2623 {
2624 curr_running_disp->set_CRD(i,sc_logic(0));
2625 }
2626 }
2627
2628 // Calculate Disparity for lane #
2629 for(i=0;i<LINK_WIDTH;i++)
2630 {
2631 if(curr_running_disp->get_CRD(i).to_bool())
2632 {
2633 iter = map_table->data_encode_map.find(i);
2634 ts1_link_lane_non_PAD[i].range(20,29) = iter->second;
2635 }
2636 else if(!curr_running_disp->get_CRD(i).to_bool())
2637 {
2638 iter = map_table->neg_data_encode_map.find(i);
2639 ts1_link_lane_non_PAD[i].range(20,29) = (iter->second);
2640 }
2641 if(curr_running_disp->calculate_disparity(ts1_link_lane_non_PAD[i].range(20,29),0) == 1)
2642 {
2643 curr_running_disp->set_CRD(i,sc_logic(1));
2644 }
2645 else if(curr_running_disp->calculate_disparity(ts1_link_lane_non_PAD[i].range(20,29),0) == 0)
2646 {
2647 curr_running_disp->set_CRD(i,sc_logic(0));
2648 }
2649 }
2650
2651 for(i=0;i<LINK_WIDTH;i++)
2652 {
2653 if(curr_running_disp->get_CRD(i).to_bool())
2654 {
2655 ts1_link_lane_non_PAD[i].range(30,39) = 0x15a;
2656 iter = map_table->data_encode_map.find(D2_0);
2657 ts1_link_lane_non_PAD[i].range(40,49) = iter->second;
2658 iter = map_table->data_encode_map.find(D0_0);
2659 ts1_link_lane_non_PAD[i].range(50,59) = iter->second;
2660 }
2661 else if(!curr_running_disp->get_CRD(i).to_bool())
2662 {
2663 ts1_link_lane_non_PAD[i].range(30,39) = 0x15a; // Neutral
2664 iter = map_table->neg_data_encode_map.find(D2_0);
2665 ts1_link_lane_non_PAD[i].range(40,49) = (iter->second); // Neutral
2666 iter = map_table->neg_data_encode_map.find(D0_0);
2667 ts1_link_lane_non_PAD[i].range(50,59) = (iter->second); // Neutral
2668 }
2669 }
2670 }
2671
2672 /// Go ahead with the transmission of the current state patterns
2673 if(ts1_non_pad_link_bit == 0 && ts1_non_pad_lane_bit == 0) // Previous transmission must have completed
2674 {
2675 for(i=0;i<LINK_WIDTH;i++)
2676 {
2677 if(LINK_WIDTH == 1)
2678 out_reg = (ts1_link_lane_non_PAD[i].range(ts1_non_pad_link_lane,ts1_non_pad_link_lane));
2679 else
2680 out_reg = (ts1_link_lane_non_PAD[i].range(ts1_non_pad_link_lane,ts1_non_pad_link_lane),out_reg.range(LINK_WIDTH-1,1));
2681 out_reg_bar = ~out_reg;
2682 }
2683 if(ts1_non_pad_link_lane == 0)
2684 scrambler_i->scramble_descramble_all(K28_5,1,1);
2685 else if((ts1_non_pad_link_lane % 10) == 0)
2686 {
2687 for(int lane_scram = 0;lane_scram < LINK_WIDTH; lane_scram++)
2688 {
2689 scrambler_i->start_scramble_reg[lane_scram] = true;
2690 scrambler_i->scramble_descramble(0x00,1,0,lane_scram); // Move forward the LFSR
2691 }
2692 }
2693
2694 ts1_non_pad_link_lane += 1;
2695 ts1_non_pad_link_lane %= 160;
2696 }
2697 else if(ts1_non_pad_lane_bit != 0)
2698 {
2699 for(i=0;i<LINK_WIDTH;i++)
2700 {
2701 if(LINK_WIDTH == 1)
2702 out_reg = (ts1_link_lane_non_PAD[i].range(ts1_non_pad_lane_bit,ts1_non_pad_lane_bit));
2703 else
2704 out_reg = (ts1_link_lane_non_PAD[i].range(ts1_non_pad_lane_bit,ts1_non_pad_lane_bit),out_reg.range(LINK_WIDTH-1,1));
2705 out_reg_bar = ~out_reg;
2706 }
2707 if(ts1_non_pad_lane_bit == 0)
2708 scrambler_i->scramble_descramble_all(K28_5,1,1);
2709 else if((ts1_non_pad_lane_bit %10) == 0)
2710 {
2711 for(int lane_scram = 0;lane_scram < LINK_WIDTH; lane_scram++)
2712 {
2713 scrambler_i->start_scramble_reg[lane_scram] = true;
2714 scrambler_i->scramble_descramble(0x00,1,0,lane_scram); // Move forward the LFSR
2715 }
2716 }
2717
2718 ts1_non_pad_lane_bit += 1;
2719 ts1_non_pad_lane_bit %= 160;
2720 }
2721 else// Finish off the previous transmission
2722 {
2723 for(i=0;i<LINK_WIDTH;i++)
2724 {
2725 if(LINK_WIDTH == 1)
2726 out_reg = (ts1_link_num_non_PAD[i].range(ts1_non_pad_link_bit,ts1_non_pad_link_bit));
2727 else
2728 out_reg = (ts1_link_num_non_PAD[i].range(ts1_non_pad_link_bit,ts1_non_pad_link_bit),out_reg.range(LINK_WIDTH-1,1));
2729 out_reg_bar = ~out_reg;
2730 }
2731 if(ts1_non_pad_link_bit == 0)
2732 scrambler_i->scramble_descramble_all(K28_5,1,1);
2733 else if((ts1_non_pad_link_bit % 10) == 0)
2734 {
2735 for(int lane_scram = 0;lane_scram < LINK_WIDTH; lane_scram++)
2736 {
2737 scrambler_i->start_scramble_reg[lane_scram] = true;
2738 scrambler_i->scramble_descramble(0x00,1,0,lane_scram); // Move forward the LFSR
2739 }
2740 }
2741 ts1_non_pad_link_bit++;
2742 ts1_non_pad_link_bit %= 160;
2743 }
2744 }
2745
2746 if(init_state == Recovery_RcvrLock) // Recovery RcvrLock
2747 {
2748 if(ts1_non_pad_lane_bit == 0 && start_reinit.read())
2749 {
2750 for(i=0;i<LINK_WIDTH;i++)
2751 {
2752 if(curr_running_disp->get_CRD(i).to_bool())
2753 {
2754 iter = map_table->spec_symbol_map.find(K28_5);
2755 ts1_link_lane_non_PAD[i].range(0,9) = iter->second;
2756 set_delim_value(TS1_LINK_LANE_NON_PAD,i);
2757 }
2758 else if(!curr_running_disp->get_CRD(i).to_bool())
2759 {
2760 iter = map_table->neg_spec_symbol_map.find(K28_5);
2761 ts1_link_lane_non_PAD[i].range(0,9) = (iter->second);
2762 set_delim_value(TS1_LINK_LANE_NON_PAD,i);
2763 }
2764 if(curr_running_disp->calculate_disparity(ts1_link_lane_non_PAD[i].range(0,9),0) == 1)
2765 {
2766 curr_running_disp->set_CRD(i,sc_logic(1));
2767 }
2768 else if(curr_running_disp->calculate_disparity(ts1_link_lane_non_PAD[i].range(0,9),0) == 0)
2769 {
2770 curr_running_disp->set_CRD(i,sc_logic(0));
2771 }
2772 }
2773
2774 // Calculate disparity for link #
2775 for(i=0;i<LINK_WIDTH;i++)
2776 {
2777 if(curr_running_disp->get_CRD(i).to_bool())
2778 {
2779 iter = map_table->data_encode_map.find(D0_0);
2780 ts1_link_lane_non_PAD[i].range(10,19) = iter->second;
2781 }
2782 else if(!curr_running_disp->get_CRD(i).to_bool())
2783 {
2784 iter = map_table->neg_data_encode_map.find(D0_0);
2785 ts1_link_lane_non_PAD[i].range(10,19) = (iter->second); // Neutral disparity
2786 }
2787 if(curr_running_disp->calculate_disparity(ts1_link_lane_non_PAD[i].range(10,19),0) == 1)
2788 {
2789 curr_running_disp->set_CRD(i,sc_logic(1));
2790 }
2791 else if(curr_running_disp->calculate_disparity(ts1_link_lane_non_PAD[i].range(10,19),0) == 0)
2792 {
2793 curr_running_disp->set_CRD(i,sc_logic(0));
2794 }
2795 }
2796
2797 // Calculate Disparity for lane #
2798 for(i=0;i<LINK_WIDTH;i++)
2799 {
2800 if(curr_running_disp->get_CRD(i).to_bool())
2801 {
2802 iter = map_table->data_encode_map.find(i);
2803 ts1_link_lane_non_PAD[i].range(20,29) = iter->second;
2804 }
2805 else if(!curr_running_disp->get_CRD(i).to_bool())
2806 {
2807 iter = map_table->neg_data_encode_map.find(i);
2808 ts1_link_lane_non_PAD[i].range(20,29) = (iter->second);
2809 }
2810 if(curr_running_disp->calculate_disparity(ts1_link_lane_non_PAD[i].range(20,29),0) == 1)
2811 {
2812 curr_running_disp->set_CRD(i,sc_logic(1));
2813 }
2814 else if(curr_running_disp->calculate_disparity(ts1_link_lane_non_PAD[i].range(20,29),0) == 0)
2815 {
2816 curr_running_disp->set_CRD(i,sc_logic(0));
2817 }
2818 }
2819
2820 for(i=0;i<LINK_WIDTH;i++)
2821 {
2822 if(curr_running_disp->get_CRD(i).to_bool())
2823 {
2824 ts1_link_lane_non_PAD[i].range(30,39) = 0x15a;
2825 iter = map_table->data_encode_map.find(D2_0);
2826 ts1_link_lane_non_PAD[i].range(40,49) = iter->second;
2827 iter = map_table->data_encode_map.find(D0_0);
2828 ts1_link_lane_non_PAD[i].range(50,59) = iter->second;
2829 }
2830 else if(!curr_running_disp->get_CRD(i).to_bool())
2831 {
2832 ts1_link_lane_non_PAD[i].range(30,39) = TS2_DELIM; // Neutral
2833 iter = map_table->neg_data_encode_map.find(D2_0);
2834 ts1_link_lane_non_PAD[i].range(40,49) = (iter->second); // Neutral
2835 iter = map_table->neg_data_encode_map.find(D0_0);
2836 ts1_link_lane_non_PAD[i].range(50,59) = (iter->second); // Neutral
2837 }
2838 }
2839 }
2840
2841 /// pl_top instructing LTSSM that it is ready to transfer control to it. Thus, start transmitting recovery training patterns
2842 if(start_reinit.read())
2843 {
2844 for(i=0;i<LINK_WIDTH;i++)
2845 {
2846 if(LINK_WIDTH == 1)
2847 out_reg = (ts1_link_lane_non_PAD[i].range(ts1_non_pad_lane_bit,ts1_non_pad_lane_bit));
2848 else
2849 out_reg = (ts1_link_lane_non_PAD[i].range(ts1_non_pad_lane_bit,ts1_non_pad_lane_bit),out_reg.range(LINK_WIDTH-1,1));
2850 out_reg_bar = ~out_reg;
2851 }
2852 if(ts1_non_pad_lane_bit == 0)
2853 scrambler_i->scramble_descramble_all(K28_5,1,1);
2854 else if((ts1_non_pad_lane_bit %10) == 0)
2855 {
2856 for(int lane_scram = 0;lane_scram < LINK_WIDTH; lane_scram++)
2857 {
2858 scrambler_i->start_scramble_reg[lane_scram] = true;
2859 scrambler_i->scramble_descramble(0x00,1,0,lane_scram); // Move forward the LFSR
2860 }
2861 }
2862
2863 ts1_non_pad_lane_bit += 1;
2864 ts1_non_pad_lane_bit %= 160;
2865 }
2866 }
2867
2868 if(init_state == CFG_LANENUM_WAIT) //Send the different Lane numbers received
2869 {
2870 if(ts1_non_pad_diff_lane_bit == 0 && ts1_non_pad_lane_bit == 0 && ts1_non_pad_link_lane == 0 && ts1_non_pad_link_bit == 0)
2871 {
2872 for(i=0;i<LINK_WIDTH;i++)
2873 {
2874 if(curr_running_disp->get_CRD(i).to_bool())
2875 {
2876 iter = map_table->spec_symbol_map.find(K28_5);
2877 ts1_link_lane_non_PAD[i].range(0,9) = iter->second;
2878 set_delim_value(TS1_LINK_LANE_NON_PAD,i);
2879 }
2880 else if(!curr_running_disp->get_CRD(i).to_bool())
2881 {
2882 iter = map_table->spec_symbol_map.find(K28_5);
2883 ts1_link_lane_non_PAD[i].range(0,9) = ~(iter->second);
2884 set_delim_value(TS1_LINK_LANE_NON_PAD,i);
2885 }
2886 if(curr_running_disp->calculate_disparity(ts1_link_lane_non_PAD[i].range(0,9),0) == 1)
2887 {
2888 curr_running_disp->set_CRD(i,sc_logic(1));
2889 }
2890 else if(curr_running_disp->calculate_disparity(ts1_link_lane_non_PAD[i].range(0,9),0) == 0)
2891 {
2892 curr_running_disp->set_CRD(i,sc_logic(0));
2893 }
2894 }
2895 // Calculate disparity for link #
2896 for(i=0;i<LINK_WIDTH;i++)
2897 {
2898 if(curr_running_disp->get_CRD(i).to_bool())
2899 {
2900 iter = map_table->data_encode_map.find(D0_0);
2901 ts1_link_lane_non_PAD[i].range(10,19) = iter->second;
2902 }
2903 else if(!curr_running_disp->get_CRD(i).to_bool())
2904 {
2905 iter = map_table->neg_data_encode_map.find(D0_0);
2906 ts1_link_lane_non_PAD[i].range(10,19) = (iter->second); // Neutral disparity
2907 }
2908 if(curr_running_disp->calculate_disparity(ts1_link_lane_non_PAD[i].range(10,19),0) == 1)
2909 {
2910 curr_running_disp->set_CRD(i,sc_logic(1));
2911 }
2912 else if(curr_running_disp->calculate_disparity(ts1_link_lane_non_PAD[i].range(10,19),0) == 0)
2913 {
2914 curr_running_disp->set_CRD(i,sc_logic(0));
2915 }
2916 }
2917 // Calculate Disparity for lane #
2918 for(i=0;i<LINK_WIDTH;i++)
2919 {
2920 iter1 = map_table->data_decode_map.find(ts1_lane_diff_non_PAD[i].to_uint());
2921 iter2 = map_table->neg_data_decode_map.find(ts1_lane_diff_non_PAD[i].to_uint());
2922 if(curr_running_disp->get_CRD(i).to_bool())
2923 {
2924 iter = map_table->data_encode_map.find(i);
2925
2926 ts1_link_lane_non_PAD[i].range(20,29) = iter->second;
2927 }
2928 else if(!curr_running_disp->get_CRD(i).to_bool())
2929 {
2930 iter = map_table->neg_data_encode_map.find(i);
2931
2932 ts1_link_lane_non_PAD[i].range(20,29) = (iter->second);
2933 }
2934 if(curr_running_disp->calculate_disparity(ts1_link_lane_non_PAD[i].range(20,29),0) == 1)
2935 {
2936 curr_running_disp->set_CRD(i,sc_logic(1));
2937 }
2938 else if(curr_running_disp->calculate_disparity(ts1_link_lane_non_PAD[i].range(20,29),0) == 0)
2939 {
2940 curr_running_disp->set_CRD(i,sc_logic(0));
2941 }
2942 }
2943
2944 for(i=0;i<LINK_WIDTH;i++)
2945 {
2946 if(curr_running_disp->get_CRD(i).to_bool())
2947 {
2948 ts1_link_lane_non_PAD[i].range(30,39) = 0x15a;
2949 iter = map_table->data_encode_map.find(D2_0);
2950 ts1_link_lane_non_PAD[i].range(40,49) = iter->second;
2951 iter = map_table->data_encode_map.find(D0_0);
2952 ts1_link_lane_non_PAD[i].range(50,59) = iter->second;
2953 }
2954 else if(!curr_running_disp->get_CRD(i).to_bool())
2955 {
2956 ts1_link_lane_non_PAD[i].range(30,39) = TS2_DELIM; // Neutral
2957 iter = map_table->neg_data_encode_map.find(D2_0);
2958 ts1_link_lane_non_PAD[i].range(40,49) = (iter->second); // Neutral
2959 iter = map_table->neg_data_encode_map.find(D0_0);
2960 ts1_link_lane_non_PAD[i].range(50,59) = (iter->second); // Neutral
2961 }
2962 }
2963 }
2964
2965 /// Go ahead with the transmission of current state patterns
2966 if(ts1_non_pad_lane_bit == 0 && ts1_non_pad_link_lane == 0 && ts1_non_pad_link_bit == 0)
2967 {
2968 for(i=0;i<LINK_WIDTH;i++)
2969 {
2970 if(LINK_WIDTH == 1)
2971 out_reg = (ts1_link_lane_non_PAD[i].range(ts1_non_pad_diff_lane_bit,ts1_non_pad_diff_lane_bit));
2972 else
2973 out_reg = (ts1_link_lane_non_PAD[i].range(ts1_non_pad_diff_lane_bit,ts1_non_pad_diff_lane_bit),out_reg.range(LINK_WIDTH-1,1));
2974 out_reg_bar = ~out_reg;
2975 }
2976 if(ts1_non_pad_diff_lane_bit == 0)
2977 scrambler_i->scramble_descramble_all(K28_5,1,1);
2978 else if((ts1_non_pad_diff_lane_bit %10) == 0)
2979 {
2980 for(int lane_scram = 0;lane_scram < LINK_WIDTH; lane_scram++)
2981 {
2982 scrambler_i->start_scramble_reg[lane_scram] = true;
2983 scrambler_i->scramble_descramble(0x00,1,0,lane_scram); // Move forward the LFSR
2984 }
2985 }
2986
2987 ts1_non_pad_diff_lane_bit += 1;
2988 ts1_non_pad_diff_lane_bit %= 160;
2989 }
2990
2991 /// Complete previous transmissions
2992 else if(ts1_non_pad_lane_bit == 0 && ts1_non_pad_link_bit == 0 && ts1_non_pad_link_lane != 0)
2993 {
2994 for(i=0;i<LINK_WIDTH;i++)
2995 {
2996 if(LINK_WIDTH == 1)
2997 out_reg = (ts1_link_lane_non_PAD[i].range(ts1_non_pad_link_lane,ts1_non_pad_link_lane));
2998 else
2999 out_reg = (ts1_link_lane_non_PAD[i].range(ts1_non_pad_link_lane,ts1_non_pad_link_lane),out_reg.range(LINK_WIDTH-1,1));
3000 out_reg_bar = ~out_reg;
3001 }
3002 if(ts1_non_pad_link_lane == 0)
3003 scrambler_i->scramble_descramble_all(K28_5,1,1);
3004 else if((ts1_non_pad_link_lane %10) == 0)
3005 {
3006 for(int lane_scram = 0;lane_scram < LINK_WIDTH; lane_scram++)
3007 {
3008 scrambler_i->start_scramble_reg[lane_scram] = true;
3009 scrambler_i->scramble_descramble(0x00,1,0,lane_scram); // Move forward the LFSR
3010 }
3011 }
3012
3013 ts1_non_pad_link_lane += 1;
3014 ts1_non_pad_link_lane %= 160;
3015 }
3016
3017 /// Complete previous transmissions
3018 else if(ts1_non_pad_lane_bit != 0 && ts1_non_pad_link_lane == 0 && ts1_non_pad_link_bit == 0)
3019 {
3020 for(i=0;i<LINK_WIDTH;i++)
3021 {
3022 if(LINK_WIDTH == 1)
3023 out_reg = (ts1_link_lane_non_PAD[i].range(ts1_non_pad_lane_bit,ts1_non_pad_lane_bit));
3024 else
3025 out_reg = (ts1_link_lane_non_PAD[i].range(ts1_non_pad_lane_bit,ts1_non_pad_lane_bit),out_reg.range(LINK_WIDTH-1,1));
3026 out_reg_bar = ~out_reg;
3027 }
3028 if(ts1_non_pad_lane_bit == 0)
3029 scrambler_i->scramble_descramble_all(K28_5,1,1);
3030 else if((ts1_non_pad_lane_bit %10) == 0)
3031 {
3032 for(int lane_scram = 0;lane_scram < LINK_WIDTH; lane_scram++)
3033 {
3034 scrambler_i->start_scramble_reg[lane_scram] = true;
3035 scrambler_i->scramble_descramble(0x00,1,0,lane_scram); // Move forward the LFSR
3036 }
3037 }
3038
3039 ts1_non_pad_lane_bit += 1;
3040 ts1_non_pad_lane_bit %= 160;
3041 }
3042 else if(ts1_non_pad_lane_bit == 0 && ts1_non_pad_link_lane == 0 && ts1_non_pad_link_bit != 0)
3043 {
3044 for(i=0;i<LINK_WIDTH;i++)
3045 {
3046 if(LINK_WIDTH == 1)
3047 out_reg = (ts1_link_num_non_PAD[i].range(ts1_non_pad_link_bit,ts1_non_pad_link_bit));
3048 else
3049 out_reg = (ts1_link_num_non_PAD[i].range(ts1_non_pad_link_bit,ts1_non_pad_link_bit),out_reg.range(LINK_WIDTH-1,1));
3050 out_reg_bar = ~out_reg;
3051
3052 }
3053 if(ts1_non_pad_link_bit == 0)
3054 scrambler_i->scramble_descramble_all(K28_5,1,1);
3055 else if((ts1_non_pad_link_bit % 10) == 0)
3056 {
3057 for(int lane_scram = 0;lane_scram < LINK_WIDTH; lane_scram++)
3058 {
3059 scrambler_i->start_scramble_reg[lane_scram] = true;
3060 scrambler_i->scramble_descramble(0x00,1,0,lane_scram); // Move forward the LFSR
3061 }
3062 }
3063
3064 ts1_non_pad_link_bit++;
3065 ts1_non_pad_link_bit %= 160;
3066 }
3067 }
3068
3069 /// init_state = HOT_RESET. HOT_RESET0 is the transient state when the state machine has not yet transferred form
3070 /// Recovery_Idle to HOT_RESET
3071 if(init_state == HOT_RESET0 || init_state == HOT_RESET)
3072 {
3073 if(symbol_num == 0 && idle_pattern_bit == 0 && ts1_non_pad_lane_bit == 0)
3074 {
3075 for(i=0;i<LINK_WIDTH;i++)
3076 {
3077 if(curr_running_disp->get_CRD(i).to_bool())
3078 {
3079 iter = map_table->spec_symbol_map.find(K28_5);
3080 ts1_link_lane_non_PAD[i].range(0,9) = iter->second;
3081 set_delim_value(TS1_LINK_LANE_NON_PAD,i);
3082 }
3083 else if(!curr_running_disp->get_CRD(i).to_bool())
3084 {
3085 iter = map_table->spec_symbol_map.find(K28_5);
3086 ts1_link_lane_non_PAD[i].range(0,9) = ~(iter->second);
3087 set_delim_value(TS1_LINK_LANE_NON_PAD,i);
3088 }
3089 if(curr_running_disp->calculate_disparity(ts1_link_lane_non_PAD[i].range(0,9),0) == 1)
3090 {
3091 curr_running_disp->set_CRD(i,sc_logic(1));
3092 }
3093 else if(curr_running_disp->calculate_disparity(ts1_link_lane_non_PAD[i].range(0,9),0) == 0)
3094 {
3095 curr_running_disp->set_CRD(i,sc_logic(0));
3096 }
3097 }
3098
3099 // Calculate disparity for link #
3100 for(i=0;i<LINK_WIDTH;i++)
3101 {
3102 if(curr_running_disp->get_CRD(i).to_bool())
3103 {
3104 iter = map_table->data_encode_map.find(D0_0);
3105 ts1_link_lane_non_PAD[i].range(10,19) = iter->second;
3106 }
3107 else if(!curr_running_disp->get_CRD(i).to_bool())
3108 {
3109 iter = map_table->neg_data_encode_map.find(D0_0);
3110 ts1_link_lane_non_PAD[i].range(10,19) = (iter->second); // Neutral disparity
3111 }
3112 if(curr_running_disp->calculate_disparity(ts1_link_lane_non_PAD[i].range(10,19),0) == 1)
3113 {
3114 curr_running_disp->set_CRD(i,sc_logic(1));
3115 }
3116 else if(curr_running_disp->calculate_disparity(ts1_link_lane_non_PAD[i].range(10,19),0) == 0)
3117 {
3118 curr_running_disp->set_CRD(i,sc_logic(0));
3119 }
3120 }
3121
3122 // Calculate Disparity for lane #
3123 for(i=0;i<LINK_WIDTH;i++)
3124 {
3125 if(curr_running_disp->get_CRD(i).to_bool())
3126 {
3127 iter = map_table->data_encode_map.find(i);
3128 ts1_link_lane_non_PAD[i].range(20,29) = iter->second;
3129 }
3130 else if(!curr_running_disp->get_CRD(i).to_bool())
3131 {
3132 iter = map_table->neg_data_encode_map.find(i);
3133 ts1_link_lane_non_PAD[i].range(20,29) = (iter->second);
3134 }
3135 if(curr_running_disp->calculate_disparity(ts1_link_lane_non_PAD[i].range(20,29),0) == 1)
3136 {
3137 curr_running_disp->set_CRD(i,sc_logic(1));
3138 }
3139 else if(curr_running_disp->calculate_disparity(ts1_link_lane_non_PAD[i].range(20,29),0) == 0)
3140 {
3141 curr_running_disp->set_CRD(i,sc_logic(0));
3142 }
3143 }
3144
3145 for(i=0;i<LINK_WIDTH;i++)
3146 {
3147 if(curr_running_disp->get_CRD(i).to_bool())
3148 {
3149 ts1_link_lane_non_PAD[i].range(30,39) = 0x15a;
3150 iter = map_table->data_encode_map.find(D2_0);
3151 ts1_link_lane_non_PAD[i].range(40,49) = iter->second;
3152 iter = map_table->data_encode_map.find(D1_0); // Set the hot reset bit. Neutral
3153 ts1_link_lane_non_PAD[i].range(50,59) = iter->second;
3154 }
3155 else if(!curr_running_disp->get_CRD(i).to_bool())
3156 {
3157 ts1_link_lane_non_PAD[i].range(30,39) = TS2_DELIM; // Neutral
3158 iter = map_table->neg_data_encode_map.find(D2_0);
3159 ts1_link_lane_non_PAD[i].range(40,49) = (iter->second); // Neutral
3160 iter = map_table->neg_data_encode_map.find(D1_0); // Set the hot reset bit. Neutral
3161 ts1_link_lane_non_PAD[i].range(50,59) = (iter->second); // Neutral
3162 }
3163 }
3164 }
3165
3166 /// Go ahead with the current state pattern transmission
3167 if(symbol_num == 0 && idle_pattern_bit == 0) // Send TS1 with hot reset
3168 {
3169 for(i=0;i<LINK_WIDTH;i++)
3170 {
3171 if(LINK_WIDTH == 1)
3172 out_reg = (ts1_link_lane_non_PAD[i].range(ts1_non_pad_lane_bit,ts1_non_pad_lane_bit));
3173 else
3174 out_reg = (ts1_link_lane_non_PAD[i].range(ts1_non_pad_lane_bit,ts1_non_pad_lane_bit),out_reg.range(LINK_WIDTH-1,1));
3175 out_reg_bar = ~out_reg;
3176 }
3177 if(ts1_non_pad_lane_bit == 0)
3178 scrambler_i->scramble_descramble_all(K28_5,1,1);
3179 else if((ts1_non_pad_lane_bit %10) == 0)
3180 {
3181 for(int lane_scram = 0;lane_scram < LINK_WIDTH; lane_scram++)
3182 {
3183 scrambler_i->start_scramble_reg[lane_scram] = true;
3184 scrambler_i->scramble_descramble(0x00,1,0,lane_scram); // Move forward the LFSR
3185 }
3186 }
3187
3188 ts1_non_pad_lane_bit += 1;
3189 ts1_non_pad_lane_bit %= 160;
3190 }
3191
3192 /// Complete the previous transmissions if any
3193 else if(idle_pattern_bit != 0) // Finish the remaining Recovery_Idle patterns
3194 {
3195 for(i=0;i<LINK_WIDTH;i++)
3196 {
3197 if(LINK_WIDTH == 1)
3198 out_reg = (idle_set_const[i].range(idle_pattern_bit,idle_pattern_bit));
3199 else
3200 out_reg = (idle_set_const[i].range(idle_pattern_bit,idle_pattern_bit),out_reg.range(LINK_WIDTH-1,1));
3201 out_reg_bar = ~out_reg;
3202 }
3203 idle_pattern_bit += 1;
3204 idle_pattern_bit %= 10;
3205 }
3206
3207
3208 /// Complete the previous transmissions if any
3209 else if(symbol_num != 0) // Finish the remaining Recovery_RcvrCfg
3210 {
3211 for(i=0;i<LINK_WIDTH;i++)
3212 {
3213 if(LINK_WIDTH == 1)
3214 out_reg = (ts2_link_lane_non_PAD[i].range(symbol_num,symbol_num));
3215 else
3216 out_reg = (ts2_link_lane_non_PAD[i].range(symbol_num,symbol_num),out_reg.range(LINK_WIDTH-1,1));
3217 out_reg_bar = ~out_reg;
3218 }
3219 if(symbol_num == 0)
3220 scrambler_i->scramble_descramble_all(K28_5,1,1);
3221 else if((symbol_num % 10) == 0)
3222 {
3223 for(int lane_scram = 0;lane_scram < LINK_WIDTH; lane_scram++)
3224 {
3225 scrambler_i->start_scramble_reg[lane_scram] = true;
3226 scrambler_i->scramble_descramble(0x00,1,0,lane_scram); // Move forward the LFSR
3227 }
3228 }
3229
3230 symbol_num++;
3231 symbol_num %= 160;
3232 }
3233 }
3234
3235 /// init_state = CFG_LANENUM_ACCEPT
3236 if(init_state == CFG_LANENUM_ACCEPT)
3237 {
3238 // Calculate CRD for link_num_non_PAD
3239 if(ts1_non_pad_lane_bit == 0 && ts1_non_pad_link_lane == 0 && ts1_non_pad_diff_lane_bit == 0 && ts1_non_pad_link_bit == 0)
3240 {
3241 for(i=0;i<LINK_WIDTH;i++)
3242 {
3243 if(curr_running_disp->get_CRD(i).to_bool())
3244 {
3245 iter = map_table->spec_symbol_map.find(K28_5);
3246 ts1_link_lane_non_PAD[i].range(0,9) = iter->second;
3247 set_delim_value(TS1_LINK_LANE_NON_PAD,i);
3248 }
3249 else if(!curr_running_disp->get_CRD(i).to_bool())
3250 {
3251 iter = map_table->spec_symbol_map.find(K28_5);
3252 ts1_link_lane_non_PAD[i].range(0,9) = ~(iter->second);
3253 set_delim_value(TS1_LINK_LANE_NON_PAD,i);
3254 }
3255 if(curr_running_disp->calculate_disparity(ts1_link_lane_non_PAD[i].range(0,9),0) == 1)
3256 {
3257 curr_running_disp->set_CRD(i,sc_logic(1));
3258 }
3259 else if(curr_running_disp->calculate_disparity(ts1_link_lane_non_PAD[i].range(0,9),0) == 0)
3260 {
3261 curr_running_disp->set_CRD(i,sc_logic(0));
3262 }
3263 }
3264
3265 // Calculate disparity for link #
3266 for(i=0;i<LINK_WIDTH;i++)
3267 {
3268 if(curr_running_disp->get_CRD(i).to_bool())
3269 {
3270 iter = map_table->data_encode_map.find(D0_0);
3271 ts1_link_lane_non_PAD[i].range(10,19) = iter->second;
3272 }
3273 else if(!curr_running_disp->get_CRD(i).to_bool())
3274 {
3275 iter = map_table->neg_data_encode_map.find(D0_0);
3276 ts1_link_lane_non_PAD[i].range(10,19) = (iter->second); // Neutral disparity
3277 }
3278 if(curr_running_disp->calculate_disparity(ts1_link_lane_non_PAD[i].range(10,19),0) == 1)
3279 {
3280 curr_running_disp->set_CRD(i,sc_logic(1));
3281 }
3282 else if(curr_running_disp->calculate_disparity(ts1_link_lane_non_PAD[i].range(10,19),0) == 0)
3283 {
3284 curr_running_disp->set_CRD(i,sc_logic(0));
3285 }
3286 }
3287
3288 // Calculate Disparity for lane #
3289 for(i=0;i<LINK_WIDTH;i++)
3290 {
3291 iter1 = map_table->data_decode_map.find(ts1_lane_diff_non_PAD[i].to_uint());
3292 iter2 = map_table->neg_data_decode_map.find(ts1_lane_diff_non_PAD[i].to_uint());
3293 if(curr_running_disp->get_CRD(i).to_bool())
3294 {
3295 if(iter1 != map_table->data_decode_map.end())
3296 ts1_lane_diff_non_PAD[i].range(7,0) = iter1->second;
3297 else
3298 ts1_lane_diff_non_PAD[i].range(7,0) = iter2->second;
3299
3300 if(from_cfg_lanenum_wait)
3301 {
3302 iter = map_table->data_encode_map.find(i);
3303 }
3304 else
3305 iter = map_table->data_encode_map.find(i);
3306 ts1_link_lane_non_PAD[i].range(20,29) = iter->second;
3307 }
3308 else if(!curr_running_disp->get_CRD(i).to_bool())
3309 {
3310 if(from_cfg_lanenum_wait)
3311 {
3312 iter = map_table->neg_data_encode_map.find(i);
3313 }
3314 else
3315 iter = map_table->neg_data_encode_map.find(i);
3316 ts1_link_lane_non_PAD[i].range(20,29) = (iter->second);
3317 }
3318 if(curr_running_disp->calculate_disparity(ts1_link_lane_non_PAD[i].range(20,29),0) == 1)
3319 {
3320 curr_running_disp->set_CRD(i,sc_logic(1));
3321 }
3322 else if(curr_running_disp->calculate_disparity(ts1_link_lane_non_PAD[i].range(20,29),0) == 0)
3323 {
3324 curr_running_disp->set_CRD(i,sc_logic(0));
3325 }
3326 }
3327
3328 for(i=0;i<LINK_WIDTH;i++)
3329 {
3330 if(curr_running_disp->get_CRD(i).to_bool())
3331 {
3332 ts1_link_lane_non_PAD[i].range(30,39) = 0x15a;
3333 iter = map_table->data_encode_map.find(D2_0);
3334 ts1_link_lane_non_PAD[i].range(40,49) = iter->second;
3335 iter = map_table->data_encode_map.find(D0_0);
3336 ts1_link_lane_non_PAD[i].range(50,59) = iter->second;
3337 }
3338 else if(!curr_running_disp->get_CRD(i).to_bool())
3339 {
3340 ts1_link_lane_non_PAD[i].range(30,39) = TS2_DELIM; // Neutral
3341 iter = map_table->neg_data_encode_map.find(D2_0);
3342 ts1_link_lane_non_PAD[i].range(40,49) = (iter->second); // Neutral
3343 iter = map_table->neg_data_encode_map.find(D0_0);
3344 ts1_link_lane_non_PAD[i].range(50,59) = (iter->second); // Neutral
3345 }
3346 }
3347 }
3348
3349 /// Go ahead with the current state transmissions
3350 if(ts1_non_pad_link_lane == 0 && ts1_non_pad_diff_lane_bit == 0 && ts1_non_pad_link_bit == 0)
3351 {
3352 for(i=0;i<LINK_WIDTH;i++)
3353 {
3354 if(LINK_WIDTH == 1)
3355 out_reg = (ts1_link_lane_non_PAD[i].range(ts1_non_pad_lane_bit,ts1_non_pad_lane_bit));
3356 else
3357 out_reg = (ts1_link_lane_non_PAD[i].range(ts1_non_pad_lane_bit,ts1_non_pad_lane_bit),out_reg.range(LINK_WIDTH-1,1));
3358 out_reg_bar = ~out_reg;
3359 }
3360 if(ts1_non_pad_lane_bit == 0)
3361 scrambler_i->scramble_descramble_all(K28_5,1,1);
3362 else if((ts1_non_pad_lane_bit %10) == 0)
3363 {
3364 for(int lane_scram = 0;lane_scram < LINK_WIDTH; lane_scram++)
3365 {
3366 scrambler_i->start_scramble_reg[lane_scram] = true;
3367 scrambler_i->scramble_descramble(0x00,1,0,lane_scram); // Move forward the LFSR
3368 }
3369 }
3370
3371 ts1_non_pad_lane_bit += 1;
3372 ts1_non_pad_lane_bit %= 160;
3373 }
3374
3375 /// Complete previous transmissions
3376 else if(ts1_non_pad_link_lane != 0)
3377 {
3378 // Complete the previous patterns
3379 for(i=0;i<LINK_WIDTH;i++)
3380 {
3381 if(LINK_WIDTH == 1)
3382 out_reg = (ts1_link_lane_non_PAD[i].range(ts1_non_pad_link_lane,ts1_non_pad_link_lane));
3383 else
3384 out_reg = (ts1_link_lane_non_PAD[i].range(ts1_non_pad_link_lane,ts1_non_pad_link_lane),out_reg.range(LINK_WIDTH-1,1));
3385 out_reg_bar = ~out_reg;
3386 }
3387 if(ts1_non_pad_link_lane == 0)
3388 scrambler_i->scramble_descramble_all(K28_5,1,1);
3389 else if((ts1_non_pad_link_lane %10) == 0)
3390 {
3391 for(int lane_scram = 0;lane_scram < LINK_WIDTH; lane_scram++)
3392 {
3393 scrambler_i->start_scramble_reg[lane_scram] = true;
3394 scrambler_i->scramble_descramble(0x00,1,0,lane_scram); // Move forward the LFSR
3395 }
3396 }
3397 ts1_non_pad_link_lane++;
3398 ts1_non_pad_link_lane %= 160;
3399 }
3400
3401 /// Complete previous transmissions
3402 else if(ts1_non_pad_diff_lane_bit != 0)
3403 {
3404 // Complete the previous patterns
3405 for(i=0;i<LINK_WIDTH;i++)
3406 {
3407 if(LINK_WIDTH == 1)
3408 out_reg = (ts1_link_lane_non_PAD[i].range(ts1_non_pad_diff_lane_bit,ts1_non_pad_diff_lane_bit));
3409 else
3410 out_reg = (ts1_link_lane_non_PAD[i].range(ts1_non_pad_diff_lane_bit,ts1_non_pad_diff_lane_bit),out_reg.range(LINK_WIDTH-1,1));
3411 out_reg_bar = ~out_reg;
3412 }
3413 if(ts1_non_pad_diff_lane_bit == 0)
3414 scrambler_i->scramble_descramble_all(K28_5,1,1);
3415 else if((ts1_non_pad_diff_lane_bit %10) == 0)
3416 {
3417 for(int lane_scram = 0;lane_scram < LINK_WIDTH; lane_scram++)
3418 {
3419 scrambler_i->start_scramble_reg[lane_scram] = true;
3420 scrambler_i->scramble_descramble(0x00,1,0,lane_scram); // Move forward the LFSR
3421 }
3422 }
3423 ts1_non_pad_diff_lane_bit++;
3424 ts1_non_pad_diff_lane_bit %= 160;
3425 }
3426 else if(ts1_non_pad_link_bit != 0)
3427 {
3428 for(i=0;i<LINK_WIDTH;i++)
3429 {
3430 if(LINK_WIDTH == 1)
3431 out_reg = (ts1_link_num_non_PAD[i].range(ts1_non_pad_link_bit,ts1_non_pad_link_bit));
3432 else
3433 out_reg = (ts1_link_num_non_PAD[i].range(ts1_non_pad_link_bit,ts1_non_pad_link_bit),out_reg.range(LINK_WIDTH-1,1));
3434 out_reg_bar = ~out_reg;
3435 }
3436 if(ts1_non_pad_link_bit == 0)
3437 scrambler_i->scramble_descramble_all(K28_5,1,1);
3438 else if((ts1_non_pad_link_bit % 10) == 0)
3439 {
3440 for(int lane_scram = 0;lane_scram < LINK_WIDTH; lane_scram++)
3441 {
3442 scrambler_i->start_scramble_reg[lane_scram] = true;
3443 scrambler_i->scramble_descramble(0x00,1,0,lane_scram); // Move forward the LFSR
3444 }
3445 }
3446
3447 ts1_non_pad_link_bit++;
3448 ts1_non_pad_link_bit %= 160;
3449 }
3450 }
3451
3452 /// init_state = Recovery Receiver Config
3453 if((received_1xts2_sets || received_1xts1_sets) && init_state == Recovery_RcvrCfg)
3454 {
3455 if(symbol_num == 0 && ts1_non_pad_lane_bit == 0)
3456 {
3457 for(i=0;i<LINK_WIDTH;i++)
3458 {
3459 if(curr_running_disp->get_CRD(i).to_bool())
3460 {
3461 iter = map_table->spec_symbol_map.find(K28_5);
3462 ts2_link_lane_non_PAD[i].range(0,9) = iter->second;
3463 set_delim_value(TS2_LINK_LANE_NON_PAD,i);
3464 }
3465 else if(!curr_running_disp->get_CRD(i).to_bool())
3466 {
3467 iter = map_table->neg_spec_symbol_map.find(K28_5);
3468 ts2_link_lane_non_PAD[i].range(0,9) = (iter->second);
3469 set_delim_value(TS2_LINK_LANE_NON_PAD,i);
3470 }
3471 if(curr_running_disp->calculate_disparity(ts2_link_lane_non_PAD[i].range(0,9),0) == 1)
3472 {
3473 curr_running_disp->set_CRD(i,sc_logic(1));
3474 }
3475 else if(curr_running_disp->calculate_disparity(ts2_link_lane_non_PAD[i].range(0,9),0) == 0)
3476 {
3477 curr_running_disp->set_CRD(i,sc_logic(0));
3478 }
3479 }
3480
3481 // Calculate disparity for link #
3482 for(i=0;i<LINK_WIDTH;i++)
3483 {
3484 if(curr_running_disp->get_CRD(i).to_bool())
3485 {
3486 iter = map_table->data_encode_map.find(D0_0);
3487 ts2_link_lane_non_PAD[i].range(10,19) = iter->second;
3488 }
3489 else if(!curr_running_disp->get_CRD(i).to_bool())
3490 {
3491 iter = map_table->neg_data_encode_map.find(D0_0);
3492 ts2_link_lane_non_PAD[i].range(10,19) = (iter->second); // Neutral disparity
3493 }
3494 if(curr_running_disp->calculate_disparity(ts2_link_lane_non_PAD[i].range(10,19),0) == 1)
3495 {
3496 curr_running_disp->set_CRD(i,sc_logic(1));
3497 }
3498 else if(curr_running_disp->calculate_disparity(ts2_link_lane_non_PAD[i].range(10,19),0) == 0)
3499 {
3500 curr_running_disp->set_CRD(i,sc_logic(0));
3501 }
3502 }
3503
3504 // Calculate Disparity for lane #
3505 for(i=0;i<LINK_WIDTH;i++)
3506 {
3507 if(curr_running_disp->get_CRD(i).to_bool())
3508 {
3509 iter = map_table->data_encode_map.find(i);
3510 ts2_link_lane_non_PAD[i].range(20,29) = iter->second;
3511 }
3512 else if(!curr_running_disp->get_CRD(i).to_bool())
3513 {
3514 iter = map_table->neg_data_encode_map.find(i);
3515 ts2_link_lane_non_PAD[i].range(20,29) = (iter->second);
3516 }
3517 if(curr_running_disp->calculate_disparity(ts2_link_lane_non_PAD[i].range(20,29),0) == 1)
3518 {
3519 curr_running_disp->set_CRD(i,sc_logic(1));
3520 }
3521 else if(curr_running_disp->calculate_disparity(ts2_link_lane_non_PAD[i].range(20,29),0) == 0)
3522 {
3523 curr_running_disp->set_CRD(i,sc_logic(0));
3524 }
3525 }
3526
3527 for(i=0;i<LINK_WIDTH;i++)
3528 {
3529 if(curr_running_disp->get_CRD(i).to_bool())
3530 {
3531 ts2_link_lane_non_PAD[i].range(30,39) = 0x15a;
3532 iter = map_table->data_encode_map.find(D2_0);
3533 ts2_link_lane_non_PAD[i].range(40,49) = iter->second;
3534 iter = map_table->data_encode_map.find(D0_0);
3535 ts2_link_lane_non_PAD[i].range(50,59) = iter->second;
3536 }
3537 else if(!curr_running_disp->get_CRD(i).to_bool())
3538 {
3539 ts2_link_lane_non_PAD[i].range(30,39) = 0x15a; // Neutral
3540 iter = map_table->neg_data_encode_map.find(D2_0);
3541 ts2_link_lane_non_PAD[i].range(40,49) = (iter->second); // Neutral
3542 iter = map_table->neg_data_encode_map.find(D0_0);
3543 ts2_link_lane_non_PAD[i].range(50,59) = (iter->second); // Neutral
3544 }
3545 }
3546 }
3547 if(ts1_non_pad_lane_bit == 0) // Previous patterns completed
3548 {
3549 if(transmit_ts2_count == 0)
3550 transmit_ts2_count = 17;
3551 if(transmit_ts2_count != 0)
3552 {
3553 for(i=0;i<LINK_WIDTH;i++)
3554 {
3555 if(LINK_WIDTH == 1)
3556 out_reg = (ts2_link_lane_non_PAD[i].range(symbol_num,symbol_num));
3557 else
3558 out_reg = (ts2_link_lane_non_PAD[i].range(symbol_num,symbol_num),out_reg.range(LINK_WIDTH-1,1));
3559 out_reg_bar = ~out_reg;
3560 }
3561 if(symbol_num == 0)
3562 {
3563 scrambler_i->scramble_descramble_all(K28_5,1,1);
3564 }
3565 else if((symbol_num % 10) == 0)
3566 {
3567 for(int lane_scram = 0;lane_scram < LINK_WIDTH; lane_scram++)
3568 {
3569 scrambler_i->start_scramble_reg[lane_scram] = true;
3570 scrambler_i->scramble_descramble(0x00,1,0,lane_scram); // Move forward the LFSR
3571 }
3572 }
3573
3574 symbol_num++;
3575 symbol_num %= 160;
3576 if(symbol_num == 0)
3577 {
3578 transmit_ts2_count--;
3579 transmitted_ts2_pattern += 1;
3580
3581 if(transmit_ts2_count == 0)
3582 transmitted_16xts2_sets = 1;
3583 }
3584 }
3585 else
3586 {
3587 transmitted_16xts2_sets = 1;
3588 received_8xts2_sets = 0;
3589 }
3590 }
3591 else // Complete the previous sequence
3592 {
3593 for(i=0;i<LINK_WIDTH;i++)
3594 {
3595 if(LINK_WIDTH == 1)
3596 out_reg = (ts1_link_lane_non_PAD[i].range(ts1_non_pad_lane_bit,ts1_non_pad_lane_bit));
3597 else
3598 out_reg = (ts1_link_lane_non_PAD[i].range(ts1_non_pad_lane_bit,ts1_non_pad_lane_bit),out_reg.range(LINK_WIDTH-1,1));
3599 out_reg_bar = ~out_reg;
3600 }
3601 if(ts1_non_pad_lane_bit == 0)
3602 scrambler_i->scramble_descramble_all(K28_5,1,1);
3603 else if((ts1_non_pad_lane_bit % 10) == 0)
3604 {
3605 for(int lane_scram = 0;lane_scram < LINK_WIDTH; lane_scram++)
3606 {
3607 scrambler_i->start_scramble_reg[lane_scram] = true;
3608 scrambler_i->scramble_descramble(0x00,1,0,lane_scram); // Move forward the LFSR
3609 }
3610 }
3611 ts1_non_pad_lane_bit++;
3612 ts1_non_pad_lane_bit %= 160;
3613 }
3614 }
3615
3616 /// CFG_COMPLETE
3617 if((init_state == CFG_COMPLETE) || (!received_1xidl_sets && init_state == CFG_IDLE))
3618 {
3619 // Calculate CRD for link_num_non_PAD
3620 if(symbol_num == 0 && ts1_non_pad_lane_bit == 0 && ts1_non_pad_link_lane == 0)
3621 {
3622 for(i=0;i<LINK_WIDTH;i++)
3623 {
3624 if(curr_running_disp->get_CRD(i).to_bool())
3625 {
3626 iter = map_table->spec_symbol_map.find(K28_5);
3627 ts2_link_lane_non_PAD[i].range(0,9) = iter->second;
3628 set_delim_value(TS2_LINK_LANE_NON_PAD,i);
3629 }
3630 else if(!curr_running_disp->get_CRD(i).to_bool())
3631 {
3632 iter = map_table->spec_symbol_map.find(K28_5);
3633 ts2_link_lane_non_PAD[i].range(0,9) = ~(iter->second);
3634 set_delim_value(TS2_LINK_LANE_NON_PAD,i);
3635 }
3636 if(curr_running_disp->calculate_disparity(ts2_link_lane_non_PAD[i].range(0,9),0) == 1)
3637 {
3638 curr_running_disp->set_CRD(i,sc_logic(1));
3639 }
3640 else if(curr_running_disp->calculate_disparity(ts2_link_lane_non_PAD[i].range(0,9),0) == 0)
3641 {
3642 curr_running_disp->set_CRD(i,sc_logic(0));
3643 }
3644 }
3645
3646 // Calculate disparity for link #
3647 for(i=0;i<LINK_WIDTH;i++)
3648 {
3649 if(curr_running_disp->get_CRD(i).to_bool())
3650 {
3651 iter = map_table->data_encode_map.find(D0_0);
3652 ts2_link_lane_non_PAD[i].range(10,19) = iter->second;
3653 }
3654 else if(!curr_running_disp->get_CRD(i).to_bool())
3655 {
3656 iter = map_table->neg_data_encode_map.find(D0_0);
3657 ts2_link_lane_non_PAD[i].range(10,19) = (iter->second); // Neutral disparity
3658 }
3659 if(curr_running_disp->calculate_disparity(ts2_link_lane_non_PAD[i].range(10,19),0) == 1)
3660 {
3661 curr_running_disp->set_CRD(i,sc_logic(1));
3662 }
3663 else if(curr_running_disp->calculate_disparity(ts2_link_lane_non_PAD[i].range(10,19),0) == 0)
3664 {
3665 curr_running_disp->set_CRD(i,sc_logic(0));
3666 }
3667 }
3668
3669 // Calculate Disparity for lane #
3670 for(i=0;i<LINK_WIDTH;i++)
3671 {
3672 if(curr_running_disp->get_CRD(i).to_bool())
3673 {
3674 iter = map_table->data_encode_map.find(i);
3675 ts2_link_lane_non_PAD[i].range(20,29) = iter->second;
3676 }
3677 else if(!curr_running_disp->get_CRD(i).to_bool())
3678 {
3679 iter = map_table->neg_data_encode_map.find(i);
3680 ts2_link_lane_non_PAD[i].range(20,29) = (iter->second);
3681 }
3682 if(curr_running_disp->calculate_disparity(ts2_link_lane_non_PAD[i].range(20,29),0) == 1)
3683 {
3684 curr_running_disp->set_CRD(i,sc_logic(1));
3685 }
3686 else if(curr_running_disp->calculate_disparity(ts2_link_lane_non_PAD[i].range(20,29),0) == 0)
3687 {
3688 curr_running_disp->set_CRD(i,sc_logic(0));
3689 }
3690 }
3691
3692 for(i=0;i<LINK_WIDTH;i++)
3693 {
3694 if(curr_running_disp->get_CRD(i).to_bool())
3695 {
3696 ts2_link_lane_non_PAD[i].range(30,39) = 0x9b;
3697 iter = map_table->data_encode_map.find(D2_0);
3698 ts2_link_lane_non_PAD[i].range(40,49) = iter->second;
3699 iter = map_table->data_encode_map.find(D0_0);
3700 ts2_link_lane_non_PAD[i].range(50,59) = iter->second;
3701 }
3702 else if(!curr_running_disp->get_CRD(i).to_bool())
3703 {
3704 ts2_link_lane_non_PAD[i].range(30,39) = 0x364; // Neutral
3705 iter = map_table->neg_data_encode_map.find(D2_0);
3706 ts2_link_lane_non_PAD[i].range(40,49) = (iter->second); // Neutral
3707 iter = map_table->neg_data_encode_map.find(D0_0);
3708 ts2_link_lane_non_PAD[i].range(50,59) = (iter->second); // Neutral
3709 }
3710 }
3711 }
3712 if(ts1_non_pad_lane_bit == 0 && ts1_non_pad_link_lane == 0) // Previous patterns completed
3713 {
3714
3715 if(transmit_ts2_count == 0 && !received_1xts2_sets)
3716 transmit_ts2_count = 17;
3717
3718 if(transmit_ts2_count != 0 || (!received_1xidl_sets && init_state == CFG_IDLE))
3719 {
3720 for(i=0;i<LINK_WIDTH;i++)
3721 {
3722 if(LINK_WIDTH == 1)
3723 out_reg = (ts2_link_lane_non_PAD[i].range(symbol_num,symbol_num));
3724 else
3725 out_reg = (ts2_link_lane_non_PAD[i].range(symbol_num,symbol_num),out_reg.range(LINK_WIDTH-1,1));
3726 out_reg_bar = ~out_reg;
3727 }
3728 if(symbol_num == 0)
3729 {
3730 scrambler_i->scramble_descramble_all(K28_5,1,1);
3731 }
3732 else if((symbol_num % 10) == 0)
3733 {
3734 for(int lane_scram = 0;lane_scram < LINK_WIDTH; lane_scram++)
3735 {
3736 scrambler_i->start_scramble_reg[lane_scram] = true;
3737 scrambler_i->scramble_descramble(0x00,1,0,lane_scram); // Move forward the LFSR
3738 }
3739 }
3740
3741 symbol_num++;
3742 symbol_num %= 160;
3743 if(symbol_num == 0)
3744 {
3745 transmit_ts2_count--;
3746 transmitted_ts2_pattern += 1;
3747
3748 if(transmit_ts2_count == 0)
3749 {
3750 transmit_ts2_count += 17;
3751 transmitted_16xts2_sets = 1;
3752 }
3753 }
3754 }
3755 else
3756 {
3757 transmitted_16xts2_sets = 1;
3758 received_8xts2_sets = 0;
3759 }
3760 }
3761 else if(ts1_non_pad_lane_bit != 0)// Complete the previous sequence
3762 {
3763 for(i=0;i<LINK_WIDTH;i++)
3764 {
3765 if(LINK_WIDTH == 1)
3766 out_reg = (ts1_link_lane_non_PAD[i].range(ts1_non_pad_lane_bit,ts1_non_pad_lane_bit));
3767 else
3768 out_reg = (ts1_link_lane_non_PAD[i].range(ts1_non_pad_lane_bit,ts1_non_pad_lane_bit),out_reg.range(LINK_WIDTH-1,1));
3769 out_reg_bar = ~out_reg;
3770 }
3771 if(ts1_non_pad_lane_bit == 0)
3772 scrambler_i->scramble_descramble_all(K28_5,1,1);
3773 else if((ts1_non_pad_lane_bit % 10) == 0)
3774 {
3775 for(int lane_scram = 0;lane_scram < LINK_WIDTH; lane_scram++)
3776 {
3777 scrambler_i->start_scramble_reg[lane_scram] = true;
3778 scrambler_i->scramble_descramble(0x00,1,0,lane_scram); // Move forward the LFSR
3779 }
3780 }
3781 ts1_non_pad_lane_bit++;
3782 ts1_non_pad_lane_bit %= 160;
3783 }
3784 else if(ts1_non_pad_link_lane != 0)
3785 {
3786 for(i=0;i<LINK_WIDTH;i++)
3787 {
3788 if(LINK_WIDTH == 1)
3789 out_reg = (ts1_link_lane_non_PAD[i].range(ts1_non_pad_link_lane,ts1_non_pad_link_lane));
3790 else
3791 out_reg = (ts1_link_lane_non_PAD[i].range(ts1_non_pad_link_lane,ts1_non_pad_link_lane),out_reg.range(LINK_WIDTH-1,1));
3792 out_reg_bar = ~out_reg;
3793 }
3794 if(ts1_non_pad_link_lane == 0)
3795 scrambler_i->scramble_descramble_all(K28_5,1,1);
3796 else if((ts1_non_pad_link_lane % 10) == 0)
3797 {
3798 for(int lane_scram = 0;lane_scram < LINK_WIDTH; lane_scram++)
3799 {
3800 scrambler_i->start_scramble_reg[lane_scram] = true;
3801 scrambler_i->scramble_descramble(0x00,1,0,lane_scram); // Move forward the LFSR
3802 }
3803 }
3804 ts1_non_pad_link_lane++;
3805 ts1_non_pad_link_lane %= 160;
3806 }
3807 }
3808
3809 /// Initialization is complete. Assert the init_done signal
3810 if(write_init_done)
3811 {
3812 init_done.write(true);
3813
3814 if(done_last_idle < 1 && !this_is_retraining) last_idle_frame = true;
3815 else last_idle_frame = false;
3816
3817 if(done_last_idle_retrain < 1 && retraining)
3818 last_idle_frame_retraining = true;
3819 else
3820 last_idle_frame_retraining = false;
3821 wait(SC_ZERO_TIME); // This wait is very important to make sure both PL and LTSSM do not modify the disparity engine
3822 if(done_last_idle_retrain >= 1) retraining = false;
3823 }
3824 else
3825 init_done.write(false);
3826
3827 if(stage_init_state && !write_init_done)
3828 {
3829 init_done.write(false);
3830 }
3831
3832 /// For Recovery_Idle or L0 state when control is not yet fully with pl_top. This is for Retraining sequence
3833 if(init_state == Recovery_Idle || (init_state == L0 && !init_done.read() && retraining) || (last_idle_frame_retraining) || (init_state == L0s && !init_done.read() && retraining))
3834 { // Start transmitting IDL if received IDL else normally transmit IDL patterns
3835 for(int lane_scram; lane_scram<LINK_WIDTH; lane_scram++)
3836 scrambler_i->start_scramble_reg[lane_scram] = true;
3837 if(init_state == L0)
3838 transmit_idl_count = 1;
3839 if ( transmit_idl_count != 0 || (init_state == Recovery_Idle))
3840 {
3841 // CRD calculation
3842 if(idle_pattern_bit == 0 && symbol_num == 0) // Start the scrambler only when finished transmitting previous patterns
3843 {
3844 scramble_pattern = scrambler_i->scramble_descramble_all(0x00,1,0); // LFSR moves forward...but scramble the rest with this same LFSR
3845 for(i=0;i<LINK_WIDTH;i++)
3846 {
3847 if(curr_running_disp->get_CRD(i).to_bool())
3848 {
3849 idle_set_const[i] = scramble_pattern;
3850 iter = map_table->data_encode_map.find(idle_set_const[i].to_uint());
3851 idle_set_const[i].range(0,9) = iter->second;
3852 }
3853 else if(!curr_running_disp->get_CRD(i).to_bool())
3854 {
3855 idle_set_const[i] = scramble_pattern;
3856 iter = map_table->neg_data_encode_map.find(idle_set_const[i].to_uint());
3857 idle_set_const[i].range(0,9) = iter->second;
3858 }
3859 if(curr_running_disp->calculate_disparity(idle_set_const[i].range(0,9),0) == 1)
3860 {
3861 curr_running_disp->set_CRD(i,sc_logic(1));
3862 }
3863 else if(curr_running_disp->calculate_disparity(idle_set_const[i].range(0,9),0) == 0)
3864 {
3865 curr_running_disp->set_CRD(i,sc_logic(0));
3866 }
3867 }
3868 }
3869
3870 if(symbol_num == 0)
3871 {
3872 for(i=0;i<LINK_WIDTH;i++)
3873 {
3874 if(LINK_WIDTH == 1)
3875 out_reg = (idle_set_const[i].range(idle_pattern_bit,idle_pattern_bit));
3876 else
3877 out_reg = (idle_set_const[i].range(idle_pattern_bit,idle_pattern_bit),out_reg.range(LINK_WIDTH-1,1));
3878 out_reg_bar = ~out_reg;
3879 }
3880 idle_pattern_bit += 1;
3881 idle_pattern_bit %= 10;
3882 if(idle_pattern_bit == 0)
3883 {
3884 if(transmit_idl_count > 0)
3885 transmit_idl_count--;
3886 transmitted_idl_pattern += 1;
3887
3888
3889
3890 if(transmitted_idl_pattern >= 16 && (init_state == Recovery_Idle))
3891 {
3892 transmitted_16xidl_sets = 1;
3893 transmit_idl_count+= 16;
3894 }
3895 if(init_done.read()) done_last_idle_retrain++;
3896 }
3897 }
3898 else if(symbol_num != 0)
3899 {
3900 for(i=0;i<LINK_WIDTH;i++)
3901 {
3902 if(LINK_WIDTH == 1)
3903 out_reg = (ts2_link_lane_non_PAD[i].range(symbol_num,symbol_num));
3904 else
3905 out_reg = (ts2_link_lane_non_PAD[i].range(symbol_num,symbol_num),out_reg.range(LINK_WIDTH-1,1));
3906 out_reg_bar = ~out_reg;
3907 }
3908 if(symbol_num == 0)
3909 scrambler_i->scramble_descramble_all(K28_5,1,1);
3910 else if((symbol_num % 10) == 0)
3911 {
3912 for(int lane_scram = 0;lane_scram < LINK_WIDTH; lane_scram++)
3913 {
3914 scrambler_i->start_scramble_reg[lane_scram] = true;
3915 scrambler_i->scramble_descramble(0x00,1,0,lane_scram); // Move forward the LFSR
3916 }
3917 }
3918
3919 symbol_num++;
3920 symbol_num %= 160;
3921 }
3922 }
3923 }
3924
3925 /// For CFG_IDLE and L0 when control is still not yet with pl_top. This is not a retraining sequence
3926 if ((received_1xidl_sets && init_state == CFG_IDLE) || (init_state == L0 && !init_done.read() && !retraining) || (last_idle_frame && !retraining) || (init_state == L0s && !init_done.read() && !retraining)){ // Start transmitting IDL if received IDL else normally transmit IDL patterns
3927 for(int lane_scram=0; lane_scram<LINK_WIDTH; lane_scram++)
3928 scrambler_i->start_scramble_reg[lane_scram] = true;
3929
3930 if(init_state == L0)
3931 transmit_idl_count = 1;
3932 if ( transmit_idl_count != 0 || (init_state == CFG_IDLE && !received_8xidl_sets) )
3933 {
3934 // CRD calculation
3935 if(idle_pattern_bit == 0 && symbol_num == 0) // Start the scrambler only when finished transmitting previous patterns
3936 {
3937 scramble_pattern = scrambler_i->scramble_descramble_all(0x00,1,0); // LFSR moves forward...but scramble the rest with this same LFSR
3938 for(i=0;i<LINK_WIDTH;i++)
3939 {
3940 if(curr_running_disp->get_CRD(i).to_bool())
3941 {
3942 idle_set_const[i] = scramble_pattern;
3943 iter = map_table->data_encode_map.find(idle_set_const[i].to_uint());
3944 idle_set_const[i].range(0,9) = iter->second;
3945 }
3946 else if(!curr_running_disp->get_CRD(i).to_bool())
3947 {
3948 idle_set_const[i] = scramble_pattern;
3949 iter = map_table->neg_data_encode_map.find(idle_set_const[i].to_uint());
3950 idle_set_const[i].range(0,9) = iter->second;
3951 }
3952 if(curr_running_disp->calculate_disparity(idle_set_const[i].range(0,9),0) == 1)
3953 {
3954 curr_running_disp->set_CRD(i,sc_logic(1));
3955 }
3956 else if(curr_running_disp->calculate_disparity(idle_set_const[i].range(0,9),0) == 0)
3957 {
3958 curr_running_disp->set_CRD(i,sc_logic(0));
3959 }
3960 }
3961 }
3962
3963 if(symbol_num == 0)
3964 {
3965 for(i=0;i<LINK_WIDTH;i++)
3966 {
3967 if(LINK_WIDTH == 1)
3968 out_reg = (idle_set_const[i].range(idle_pattern_bit,idle_pattern_bit));
3969 else
3970 out_reg = (idle_set_const[i].range(idle_pattern_bit,idle_pattern_bit),out_reg.range(LINK_WIDTH-1,1));
3971 out_reg_bar = ~out_reg;
3972 }
3973 idle_pattern_bit += 1;
3974 idle_pattern_bit %= 10;
3975 if(idle_pattern_bit == 0)
3976 {
3977 if(transmit_idl_count > 0)
3978 transmit_idl_count--;
3979 transmitted_idl_pattern += 1;
3980
3981 if(transmitted_idl_pattern >= 16 && (init_state == CFG_IDLE))
3982 {
3983 transmitted_16xidl_sets = 1;
3984 transmit_idl_count+= 16;
3985 }
3986 if(init_done.read()) done_last_idle++;
3987 }
3988 }
3989 else if(symbol_num != 0)
3990 {
3991 for(i=0;i<LINK_WIDTH;i++)
3992 {
3993 if(LINK_WIDTH == 1)
3994 out_reg = (ts2_link_lane_non_PAD[i].range(symbol_num,symbol_num));
3995 else
3996 out_reg = (ts2_link_lane_non_PAD[i].range(symbol_num,symbol_num),out_reg.range(LINK_WIDTH-1,1));
3997 out_reg_bar = ~out_reg;
3998 }
3999 if(symbol_num == 0)
4000 scrambler_i->scramble_descramble_all(K28_5,1,1);
4001 else if((symbol_num % 10) == 0)
4002 {
4003 for(int lane_scram = 0;lane_scram < LINK_WIDTH; lane_scram++)
4004 {
4005 scrambler_i->start_scramble_reg[lane_scram] = true;
4006 scrambler_i->scramble_descramble(0x00,1,0,lane_scram); // Move forward the LFSR
4007 }
4008 }
4009
4010 symbol_num++;
4011 symbol_num %= 160;
4012 }
4013 }
4014 }
4015 }
4016 else
4017 {
4018 ts1_2 = 0x0000000000000000000000000000000000000000;
4019 transmitted_1024xts1_2sets = 0;
4020 transmitted_16xts2_sets = 0;
4021 transmitted_16xidl_sets = 0;
4022 transmitted_ts1_pattern = 0;
4023 ts1_pattern_bit = 0;
4024 ts2_pattern_bit = 0;
4025 idle_pattern_bit = 0;
4026 received_8xts2_sets = 0;
4027 received_8xts1_sets = 0;
4028 received_1xts1_sets = 0;
4029 received_1xts2_sets = 0;
4030 ts1_non_pad_link_bit = 0;
4031 symbol_num = 0;
4032 link_field_is_PAD_ts1 = 0;
4033 lane_field_is_PAD_ts1 = 0;
4034 link_field_is_PAD_ts2 = 0;
4035 lane_field_is_PAD_ts2 = 0;
4036 link_field_is_non_PAD_ts1 = 0;
4037 lane_field_is_non_PAD_ts1 = 0;
4038 link_field_is_non_PAD_ts2 = 0;
4039 lane_field_is_non_PAD_ts2 = 0;
4040 link_field_PAD_ts1_ok = 0;
4041 link_field_PAD_ts2_ok = 0;
4042 lane_field_PAD_ts1_ok = 0;
4043 lane_field_PAD_ts2_ok = 0;
4044 elec_idle_pattern_bit = 0;
4045 com_detected_tx = false;
4046 start_frame_boundary_tx = false;
4047 frame_boundary_tx_counter = 0;
4048 }
4049 out_reg_ser = (out_reg_ser.range(8,0),out_reg.range(0,0));
4050 out_reg_ser_bar = ~out_reg_ser;
4051 wait(link_clk.negedge_event());
4052 }
4053}
4054
4055
4056
4057/// LTSSM state machine engine
4058/// always @(negedge frame_boundary)
4059void ltssm::init_state_machine()
4060{
4061 int i;
4062 csr_port.set_notify_event(PEU_CSR_A_CORE_STATUS_HW_ADDR,&csr_core_status_ev);
4063
4064 int polling_active_counter = 0;
4065 int polling_config_counter = 0;
4066 int disabled_state_counter = 0;
4067 int cfg_complete_counter = 0;
4068 int cfg_idle_counter = 0;
4069 int cfg_linkwidth_accept_counter = 0;
4070 int cfg_linkwidth_start_counter = 0;
4071 int cfg_lanenum_wait_counter = 0;
4072 int RcvrLock_counter = 0;
4073 int RcvrCfg_counter = 0;
4074 int RcvrIdle_counter = 0;
4075 int hot_reset_counter = 0;
4076
4077 while(true)
4078 {
4079 switch(init_state)
4080 {
4081 if((reset_por_l.read()))
4082 {
4083 case DETECT_QUIET :
4084 {
4085 csr_port.write_csr_mask(PEU_CSR_A_CORE_STATUS_HW_ADDR,(ILUPEU_LTSSM_DETECT_QUIET << PEU_CSR_CORE_STATUS_LTSSM_STATE_POSITION),PEU_CSR_CORE_STATUS_LTSSM_STATE_FMASK);
4086 for(i=0;i<(200 * DetectQuietDelay) ;i++)
4087 wait(link_clk.posedge_event());
4088 this_is_retraining = false;
4089 retraining = false;
4090 electrical_idle_constant_voltage_set = 0x3ff;
4091 LOG_INFO << "_LTSSM_ : DETECT_QUIET => DETECT_ACTIVE";
4092 csr_port.write_csr_mask(PEU_CSR_A_CORE_STATUS_HW_ADDR,((ILUPEU_LTSSM_DETECT_ACT) << PEU_CSR_CORE_STATUS_LTSSM_STATE_POSITION),PEU_CSR_CORE_STATUS_LTSSM_STATE_FMASK);
4093 done_last_idle = 0;
4094 done_last_idle_retrain = 0;
4095 transmitted_idl_pattern = 0;
4096 init_state = DETECT_ACTIVE;
4097
4098 break;
4099 }
4100 case DETECT_ACTIVE:
4101 {
4102 for(i=0;i< (20 * DetectQuietDelay); i++)
4103 wait(link_clk.posedge_event());
4104 init_state = POLLING_ACTIVE;
4105 csr_port.write_csr_mask(PEU_CSR_A_CORE_STATUS_HW_ADDR, ((ILUPEU_LTSSM_POLL_ACTIVE) << PEU_CSR_CORE_STATUS_LTSSM_STATE_POSITION),PEU_CSR_CORE_STATUS_LTSSM_STATE_FMASK);
4106 csr_port.write_csr_mask(PEU_CSR_A_LNK_STS_HW_ADDR,(0x1 << 11),PEU_CSR_LNK_STS_TRAIN_MASK);
4107 LOG_INFO << "_LTSSM_ : DETECT_ACTIVE => POLLING_ACTIVE";
4108 link_field_is_PAD_ts1 = 0;
4109 link_field_is_PAD_ts2 = 0;
4110 lane_field_is_PAD_ts1 = 0;
4111 lane_field_is_PAD_ts2 = 0;
4112 link_field_is_non_PAD_ts1 = 0;
4113 lane_field_is_non_PAD_ts1 = 0;
4114 link_field_is_non_PAD_ts2 = 0;
4115 lane_field_is_non_PAD_ts2 = 0;
4116 transmitted_16xts2_sets = 0;
4117 ts1_non_pad_link_bit = 0;
4118 ts1_count = 0;
4119 ts2_count = 0;
4120 symbol_num = 0;
4121 electrical_idle_constant_voltage_set = 0x3ff;
4122 break;
4123 }
4124 case POLLING_COMPLIANCE :
4125 {
4126 }
4127 case POLLING_ACTIVE :
4128 {
4129 int i;
4130 polling_active_counter++;
4131 csr_port.write_csr_mask(PEU_CSR_A_LNK_CAP_HW_ADDR,(LINK_WIDTH << 4),PEU_CSR_LNK_STS_WIDTH_MASK);
4132 csr_port.write_csr_mask(PEU_CSR_A_LNK_STS_HW_ADDR,(0x01 << 0),PEU_CSR_LNK_STS_SPEED_MASK);
4133 if(((link_field_is_PAD_ts1 >= 8) || (link_field_is_PAD_ts2 >= 8)) && ((lane_field_is_PAD_ts1 >= 8) || (lane_field_is_PAD_ts2 >= 8)) && transmitted_1024xts1_2sets) // 8 consecutive TS1/2 patterns received and 1024 transmitted
4134 {
4135 init_state = POLLING_CONFIG;
4136 csr_port.write_csr_mask(PEU_CSR_A_CORE_STATUS_HW_ADDR,(ILUPEU_LTSSM_POLL_CONFIG << PEU_CSR_CORE_STATUS_LTSSM_STATE_POSITION),PEU_CSR_CORE_STATUS_LTSSM_STATE_FMASK);
4137 // csr_port.write_csr_mask(PEU_CSR_A_TLU_STS_HW_ADDR,(0x1 << 2),0x4);
4138 LOG_INFO << "_LTSSM_ : POLLING_ACTIVE => POLLING_CONFIG";
4139 link_field_is_PAD_ts1 = 0;
4140 link_field_is_PAD_ts2 = 0;
4141 lane_field_is_PAD_ts1 = 0;
4142 lane_field_is_PAD_ts2 = 0;
4143 transmitted_16xts2_sets = 0;
4144 transmitted_1024xts1_2sets = 0;
4145 link_field_is_non_PAD_ts2 = 0;
4146 lane_field_is_non_PAD_ts2 = 0;
4147 ts1_non_pad_link_bit = 0;
4148 ts1_count = 0;
4149 ts2_count = 0;
4150 symbol_num = 0;
4151 polling_active_counter = 0;
4152 received_1xts2_sets = 0;
4153 received_1xts1_sets = 0;
4154 }
4155 else if(polling_active_counter >= POLLING_ACTIVE_TIMEOUT || !reset_l.read() || !reset_por_l.read())
4156 {
4157 if(((link_field_is_PAD_ts1 >= 1) || (link_field_is_PAD_ts2 >= 1)) && ((lane_field_is_PAD_ts1 >= 1) || (lane_field_is_PAD_ts2 >= 1)) && transmitted_1024xts1_2sets) // 8 consecutive TS1/2 patterns received and 1024 transmitted
4158 {
4159 init_state = POLLING_CONFIG;
4160 csr_port.write_csr_mask(PEU_CSR_A_CORE_STATUS_HW_ADDR,(ILUPEU_LTSSM_POLL_CONFIG << PEU_CSR_CORE_STATUS_LTSSM_STATE_POSITION),PEU_CSR_CORE_STATUS_LTSSM_STATE_FMASK);
4161 LOG_INFO << "_LTSSM_ : POLLING_ACTIVE => POLLING_CONFIG";
4162 link_field_is_PAD_ts1 = 0;
4163 link_field_is_PAD_ts2 = 0;
4164 lane_field_is_PAD_ts1 = 0;
4165 lane_field_is_PAD_ts2 = 0;
4166 transmitted_16xts2_sets = 0;
4167 link_field_is_non_PAD_ts2 = 0;
4168 lane_field_is_non_PAD_ts2 = 0;
4169 ts1_non_pad_link_bit = 0;
4170 ts1_count = 0;
4171 ts2_count = 0;
4172 symbol_num = 0;
4173 polling_active_counter = 0;
4174 }
4175 else
4176 {
4177 init_state = DETECT_QUIET;
4178 csr_port.write_csr_mask(PEU_CSR_A_CORE_STATUS_HW_ADDR,(ILUPEU_LTSSM_DETECT_QUIET << PEU_CSR_CORE_STATUS_LTSSM_STATE_POSITION),PEU_CSR_CORE_STATUS_LTSSM_STATE_FMASK);
4179 if(!reset_l.read() || !reset_por_l.read()) LOG_INFO << "_LTSSM_ : POLLING_ACTIVE => DETECT_QUIET due to reset_l/reset_por_l";
4180
4181 link_field_is_PAD_ts1 = 0;
4182 link_field_is_PAD_ts2 = 0;
4183 lane_field_is_PAD_ts1 = 0;
4184 lane_field_is_PAD_ts2 = 0;
4185 link_field_is_non_PAD_ts2 = 0;
4186 lane_field_is_non_PAD_ts2 = 0;
4187 transmitted_16xts2_sets = 0;
4188 ts1_non_pad_link_bit = 0;
4189 ts1_count = 0;
4190 ts2_count = 0;
4191 symbol_num = 0;
4192 polling_active_counter = 0;
4193 transmitted_1024xts1_2sets = 0;
4194 LOG_INFO << " : _LTSSM_ : POLLING_ACTIVE => DETECT_QUIET";
4195 //reset_var_detect_quiet();
4196 //LOG_INFO << " : _LTSSM_ : POLLING_ACTIVE => DETECT_QUIET";
4197 }
4198 }
4199 break;
4200 }
4201 case POLLING_SPEED :
4202 {
4203 break;
4204 }
4205 case POLLING_CONFIG :
4206 {
4207 polling_config_counter++;
4208 if ( (link_field_is_PAD_ts2 >= 8) && (lane_field_is_PAD_ts2 >= 8) && (transmitted_16xts2_sets))
4209 {
4210 init_state = CFG_LINKWIDTH_START;
4211 csr_port.write_csr_mask(PEU_CSR_A_CORE_STATUS_HW_ADDR,(ILUPEU_LTSSM_CFG_LINKWD_START << PEU_CSR_CORE_STATUS_LTSSM_STATE_POSITION),PEU_CSR_CORE_STATUS_LTSSM_STATE_FMASK);
4212 link_field_is_PAD_ts1 = 0;
4213 link_field_is_PAD_ts2 = 0;
4214 lane_field_is_PAD_ts1 = 0;
4215 lane_field_is_PAD_ts2 = 0;
4216 link_field_is_non_PAD_ts2 = 0;
4217 lane_field_is_non_PAD_ts2 = 0;
4218 ts1_count = 0;
4219 ts2_count = 0;
4220 transmitted_16xts2_sets = 0;
4221 symbol_num = 0;
4222 ts1_non_pad_link_bit = 0;
4223 LOG_INFO << "_LTSSM_ : POLLING_CONFIG => CFG_LINKWIDTH_START";
4224 polling_config_counter = 0;
4225 disable_link_reg = false;
4226 }
4227 else if(polling_config_counter == POLLING_CONFIG_TIMEOUT) // Go to detect after 300 TS1 pattern timeout
4228 {
4229 init_state = DETECT_QUIET;
4230 csr_port.write_csr_mask(PEU_CSR_A_CORE_STATUS_HW_ADDR,(ILUPEU_LTSSM_DETECT_ACT << PEU_CSR_CORE_STATUS_LTSSM_STATE_POSITION),PEU_CSR_CORE_STATUS_LTSSM_STATE_FMASK);
4231 link_field_is_PAD_ts1 = 0;
4232 link_field_is_PAD_ts2 = 0;
4233 lane_field_is_PAD_ts1 = 0;
4234 lane_field_is_PAD_ts2 = 0;
4235 link_field_is_non_PAD_ts1 = 0;
4236 lane_field_is_non_PAD_ts1 = 0;
4237 link_field_is_non_PAD_ts2 = 0;
4238 lane_field_is_non_PAD_ts2 = 0;
4239 transmitted_16xts2_sets = 0;
4240 ts1_count = 0;
4241 ts2_count = 0;
4242 symbol_num = 0;
4243 polling_config_counter = 0;
4244 transmitted_1024xts1_2sets = 0;
4245 ts1_non_pad_link_bit = 0;
4246 elec_idle_pattern_bit = 0;
4247
4248 //reset_var_detect_quiet();
4249 //polling_config_counter = 0;
4250 LOG_INFO << "_LTSSM_ : POLLING_CONFIG => DETECT_QUIET";
4251 }
4252 break;
4253 }
4254 case CFG_LINKWIDTH_START :
4255 {
4256 cfg_linkwidth_start_counter++;
4257 // Exit to detect state conditions
4258 if(cfg_linkwidth_start_counter >= CFG_LINKWIDTH_START_TIMEOUT || ts1_disable_link_count >= 2)
4259 {
4260 if(cfg_linkwidth_start_counter >= CFG_LINKWIDTH_START_TIMEOUT)
4261 {
4262 init_state = DETECT_QUIET;
4263 csr_port.write_csr_mask(PEU_CSR_A_CORE_STATUS_HW_ADDR,(ILUPEU_LTSSM_DETECT_QUIET << PEU_CSR_CORE_STATUS_LTSSM_STATE_POSITION),PEU_CSR_CORE_STATUS_LTSSM_STATE_FMASK);
4264 LOG_INFO << " : _LTSSM_ : CFG_LINKWIDTH_START => DETECT_QUIET";
4265 }
4266 else
4267 {
4268 init_state = DISABLED_ENTRY;
4269 csr_port.write_csr_mask(PEU_CSR_A_CORE_STATUS_HW_ADDR,(ILUPEU_LTSSM_DISABLED_ENTRY << PEU_CSR_CORE_STATUS_LTSSM_STATE_POSITION),PEU_CSR_CORE_STATUS_LTSSM_STATE_FMASK);
4270 LOG_INFO << " : _LTSSM_ : CFG_LINKWIDTH_START => DISABLED_ENTRY";
4271 }
4272 link_field_is_PAD_ts1 = 0;
4273 link_field_is_PAD_ts2 = 0;
4274 lane_field_is_PAD_ts1 = 0;
4275 lane_field_is_PAD_ts2 = 0;
4276 link_field_is_non_PAD_ts1 = 0;
4277 lane_field_is_non_PAD_ts1 = 0;
4278 link_field_is_non_PAD_ts2 = 0;
4279 lane_field_is_non_PAD_ts2 = 0;
4280 transmitted_16xts2_sets = 0;
4281 ts1_count = 0;
4282 ts2_count = 0;
4283 symbol_num = 0;
4284 cfg_linkwidth_start_counter = 0;
4285 transmitted_1024xts1_2sets = 0;
4286 elec_idle_pattern_bit = 0;
4287 ts1_disable_link_count = 0;
4288
4289 // cfg_linkwidth_start_counter = 0;
4290 // reset_var_detect_quiet();
4291 }
4292 else if ( (link_field_is_non_PAD_ts1 >= 2)) // received 2 consecutive ts1 sets with pad link bits
4293 {
4294 init_state = CFG_LINKWIDTH_ACCEPT;
4295 csr_port.write_csr_mask(PEU_CSR_A_LNK_STS_HW_ADDR,(ILUPEU_LTSSM_CFG_LINKWD_ACEPT << PEU_CSR_CORE_STATUS_LTSSM_STATE_POSITION),PEU_CSR_CORE_STATUS_LTSSM_STATE_FMASK);
4296 link_field_is_PAD_ts1 = 0;
4297 link_field_is_PAD_ts2 = 0;
4298 lane_field_is_PAD_ts1 = 0;
4299 lane_field_is_PAD_ts2 = 0;
4300 link_field_is_non_PAD_ts1 = 0;
4301 lane_field_is_non_PAD_ts1 = 0;
4302 link_field_is_non_PAD_ts2 = 0;
4303 lane_field_is_non_PAD_ts2 = 0;
4304 transmitted_16xts2_sets = 0;
4305 ts1_count = 0;
4306 ts2_count = 0;
4307 symbol_num = 0;
4308
4309 LOG_INFO << " : _LTSSM_ : CFG_LINKWIDTH_START => CFG_LINKWIDTH_ACCEPT";
4310 cfg_linkwidth_start_counter = 0;
4311 }
4312 break;
4313 }
4314 case DISABLED_ENTRY :
4315 {
4316 if(transmitted_16xts1_disabled)
4317 {
4318 init_state = DISABLED_IDLE;
4319 csr_port.write_csr_mask(PEU_CSR_A_CORE_STATUS_HW_ADDR,(ILUPEU_LTSSM_DISABLED_IDLE << PEU_CSR_CORE_STATUS_LTSSM_STATE_POSITION),PEU_CSR_CORE_STATUS_LTSSM_STATE_FMASK);
4320 link_field_is_PAD_ts1 = 0;
4321 link_field_is_PAD_ts2 = 0;
4322 lane_field_is_PAD_ts1 = 0;
4323 lane_field_is_PAD_ts2 = 0;
4324 link_field_is_non_PAD_ts1 = 0;
4325 lane_field_is_non_PAD_ts1 = 0;
4326 link_field_is_non_PAD_ts2 = 0;
4327 lane_field_is_non_PAD_ts2 = 0;
4328 transmitted_16xts2_sets = 0;
4329 ts1_count = 0;
4330 ts2_count = 0;
4331 symbol_num = 0;
4332 ts1_non_pad_link_bit = 0;
4333 cfg_linkwidth_start_counter = 0;
4334 transmitted_1024xts1_2sets = 0;
4335 elec_idle_pattern_bit = 0;
4336 ts1_disable_link_count = 0;
4337 received_electrical_idle = false;
4338 LOG_INFO << "_LTSSM_ : DISABLED_ENTRY => DISABLED_IDLE";
4339 }
4340 break;
4341 }
4342 case DISABLED_IDLE :
4343 {
4344 if(transmitted_1xelec_idle && received_electrical_idle)
4345 {
4346 init_state = DISABLED;
4347 csr_port.write_csr_mask(PEU_CSR_A_CORE_STATUS_HW_ADDR,(ILUPEU_LTSSM_DISABLED << PEU_CSR_CORE_STATUS_LTSSM_STATE_POSITION),PEU_CSR_CORE_STATUS_LTSSM_STATE_FMASK);
4348 link_field_is_PAD_ts1 = 0;
4349 link_field_is_PAD_ts2 = 0;
4350 lane_field_is_PAD_ts1 = 0;
4351 lane_field_is_PAD_ts2 = 0;
4352 link_field_is_non_PAD_ts1 = 0;
4353 lane_field_is_non_PAD_ts1 = 0;
4354 link_field_is_non_PAD_ts2 = 0;
4355 lane_field_is_non_PAD_ts2 = 0;
4356 transmitted_16xts2_sets = 0;
4357 ts1_count = 0;
4358 ts2_count = 0;
4359 symbol_num = 0;
4360 ts1_non_pad_link_bit = 0;
4361 cfg_linkwidth_start_counter = 0;
4362 transmitted_1024xts1_2sets = 0;
4363 elec_idle_pattern_bit = 0;
4364 ts1_disable_link_count = 0;
4365 LOG_INFO << "_LTSSM_ : DISABLED_IDLE => DISABLED";
4366 }
4367 break;
4368 }
4369 case DISABLED :
4370 {
4371 disabled_state_counter++;
4372 if(disabled_state_counter >= DISABLED_TIMEOUT)
4373 {
4374 init_state = DETECT_QUIET;
4375 csr_port.write_csr_mask(PEU_CSR_A_CORE_STATUS_HW_ADDR,(ILUPEU_LTSSM_DETECT_ACT << PEU_CSR_CORE_STATUS_LTSSM_STATE_POSITION),PEU_CSR_CORE_STATUS_LTSSM_STATE_FMASK);
4376 link_field_is_PAD_ts1 = 0;
4377 link_field_is_PAD_ts2 = 0;
4378 lane_field_is_PAD_ts1 = 0;
4379 lane_field_is_PAD_ts2 = 0;
4380 link_field_is_non_PAD_ts1 = 0;
4381 lane_field_is_non_PAD_ts1 = 0;
4382 link_field_is_non_PAD_ts2 = 0;
4383 lane_field_is_non_PAD_ts2 = 0;
4384 transmitted_16xts2_sets = 0;
4385 ts1_count = 0;
4386 ts2_count = 0;
4387 disabled_state_counter = 0;
4388 transmitted_1024xts1_2sets = 0;
4389 LOG_INFO << "_LTSSM_ : DISABLED => DETECT_QUIET";
4390 }
4391 break;
4392 }
4393 case CFG_LINKWIDTH_ACCEPT :
4394 {
4395 cfg_linkwidth_accept_counter++;
4396 // Directly go to CFG_LANENUM_ACCEPT
4397 if(link_field_is_non_PAD_ts1 >= 2 && lane_field_is_non_PAD_ts1 >= 2)
4398 {
4399 init_state = CFG_LANENUM_ACCEPT;
4400 csr_port.write_csr_mask(PEU_CSR_A_LNK_STS_HW_ADDR,(ILUPEU_LTSSM_CFG_LANENUM_ACEPT << PEU_CSR_CORE_STATUS_LTSSM_STATE_POSITION),PEU_CSR_CORE_STATUS_LTSSM_STATE_FMASK);
4401 link_field_is_PAD_ts1 = 0;
4402 link_field_is_PAD_ts2 = 0;
4403 lane_field_is_PAD_ts1 = 0;
4404 lane_field_is_PAD_ts2 = 0;
4405 link_field_is_non_PAD_ts1 = 0;
4406 lane_field_is_non_PAD_ts1 = 0;
4407 link_field_is_non_PAD_ts2 = 0;
4408 lane_field_is_non_PAD_ts2 = 0;
4409 transmitted_16xts2_sets = 0;
4410 ts1_count = 0;
4411 ts2_count = 0;
4412 cfg_linkwidth_accept_counter = 0;
4413
4414 LOG_INFO << "_LTSSM_ : CFG_LINKWIDTH_ACCEPT => CFG_LANENUM_ACCEPT";
4415 }
4416 else if(move_to_cfg_lanenum_wait)
4417 {
4418 init_state = CFG_LANENUM_WAIT;
4419 csr_port.write_csr_mask(PEU_CSR_A_LNK_STS_HW_ADDR,(ILUPEU_LTSSM_CFG_LANENUM_WAIT << PEU_CSR_CORE_STATUS_LTSSM_STATE_POSITION),PEU_CSR_CORE_STATUS_LTSSM_STATE_FMASK);
4420 link_field_is_PAD_ts1 = 0;
4421 link_field_is_PAD_ts2 = 0;
4422 lane_field_is_PAD_ts1 = 0;
4423 lane_field_is_PAD_ts2 = 0;
4424 link_field_is_non_PAD_ts1 = 0;
4425 lane_field_is_non_PAD_ts1 = 0;
4426 link_field_is_non_PAD_ts2 = 0;
4427 lane_field_is_non_PAD_ts2 = 0;
4428 transmitted_16xts2_sets = 0;
4429 ts1_count = 0;
4430 ts2_count = 0;
4431 LOG_INFO << "_LTSSM_ : CFG_LINKWIDTH_ACCEPT => CFG_LANENUM_WAIT";
4432 move_to_cfg_lanenum_wait = 0;
4433 cfg_linkwidth_accept_counter = 0;
4434 }
4435 else if(cfg_linkwidth_accept_counter >= CFG_LINKWIDTH_ACCEPT_TIMEOUT || (link_field_is_PAD_ts1 >= 2))
4436 {
4437 init_state = DETECT_QUIET;
4438 csr_port.write_csr_mask(PEU_CSR_A_CORE_STATUS_HW_ADDR,(ILUPEU_LTSSM_DETECT_QUIET << PEU_CSR_CORE_STATUS_LTSSM_STATE_POSITION),PEU_CSR_CORE_STATUS_LTSSM_STATE_FMASK);
4439 link_field_is_PAD_ts1 = 0;
4440 link_field_is_PAD_ts2 = 0;
4441 lane_field_is_PAD_ts1 = 0;
4442 lane_field_is_PAD_ts2 = 0;
4443 link_field_is_non_PAD_ts1 = 0;
4444 lane_field_is_non_PAD_ts1 = 0;
4445 link_field_is_non_PAD_ts2 = 0;
4446 lane_field_is_non_PAD_ts2 = 0;
4447 transmitted_16xts2_sets = 0;
4448 ts1_count = 0;
4449 ts2_count = 0;
4450 symbol_num = 0;
4451 cfg_linkwidth_accept_counter = 0;
4452 elec_idle_pattern_bit = 0;
4453
4454 // reset_var_detect_quiet();
4455 // cfg_linkwidth_accept_counter = 0;
4456 LOG_INFO << " : _LTSSM : CFG_LINKWIDTH_ACCEPT => DETECT_QUIET";
4457 }
4458 break;
4459 }
4460 case CFG_LANENUM_ACCEPT :
4461 {
4462 if((link_field_is_non_PAD_ts1 >= 2) && (lane_field_is_non_PAD_ts1 >= 2))
4463 {
4464 init_state = CFG_COMPLETE;
4465 csr_port.write_csr_mask(PEU_CSR_A_LNK_STS_HW_ADDR,(ILUPEU_LTSSM_CFG_COMPLETE << PEU_CSR_CORE_STATUS_LTSSM_STATE_POSITION),PEU_CSR_CORE_STATUS_LTSSM_STATE_FMASK);
4466 link_field_is_PAD_ts1 = 0;
4467 link_field_is_PAD_ts2 = 0;
4468 lane_field_is_PAD_ts1 = 0;
4469 lane_field_is_PAD_ts2 = 0;
4470 link_field_is_non_PAD_ts1 = 0;
4471 lane_field_is_non_PAD_ts1 = 0;
4472 link_field_is_non_PAD_ts2 = 0;
4473 lane_field_is_non_PAD_ts2 = 0;
4474 transmitted_16xts2_sets = 0;
4475 ts1_count = 0;
4476 ts2_count = 0;
4477 received_1xts2_sets = 0;
4478
4479 LOG_INFO << "_LTSSM_ : CFG_LANENUM_ACCEPT => CFG_COMPLETE";
4480 }
4481 else if((link_field_is_PAD_ts1 >= 2) && (lane_field_is_PAD_ts1 >= 2))
4482 {
4483 init_state = DETECT_QUIET;
4484 csr_port.write_csr_mask(PEU_CSR_A_CORE_STATUS_HW_ADDR,(ILUPEU_LTSSM_DETECT_QUIET << PEU_CSR_CORE_STATUS_LTSSM_STATE_POSITION),PEU_CSR_CORE_STATUS_LTSSM_STATE_FMASK);
4485 link_field_is_PAD_ts1 = 0;
4486 link_field_is_PAD_ts2 = 0;
4487 lane_field_is_PAD_ts1 = 0;
4488 lane_field_is_PAD_ts2 = 0;
4489 link_field_is_non_PAD_ts1 = 0;
4490 lane_field_is_non_PAD_ts1 = 0;
4491 link_field_is_non_PAD_ts2 = 0;
4492 lane_field_is_non_PAD_ts2 = 0;
4493 transmitted_16xts2_sets = 0;
4494 ts1_count = 0;
4495 ts2_count = 0;
4496 // reset_var_detect_quiet();
4497 LOG_INFO << "_LTSSM_ : CFG_LANENUM_ACCEPT => DETECT_QUIET";
4498 }
4499 else if(move_to_cfg_lanenum_wait)
4500 {
4501 init_state = CFG_LANENUM_WAIT;
4502 csr_port.write_csr_mask(PEU_CSR_A_CORE_STATUS_HW_ADDR,(ILUPEU_LTSSM_CFG_LANENUM_WAIT << PEU_CSR_CORE_STATUS_LTSSM_STATE_POSITION),PEU_CSR_CORE_STATUS_LTSSM_STATE_FMASK);
4503 link_field_is_PAD_ts1 = 0;
4504 link_field_is_PAD_ts2 = 0;
4505 lane_field_is_PAD_ts1 = 0;
4506 lane_field_is_PAD_ts2 = 0;
4507 link_field_is_non_PAD_ts1 = 0;
4508 lane_field_is_non_PAD_ts1 = 0;
4509 link_field_is_non_PAD_ts2 = 0;
4510 lane_field_is_non_PAD_ts2 = 0;
4511 transmitted_16xts2_sets = 0;
4512 ts1_count = 0;
4513 ts2_count = 0;
4514 LOG_INFO << "_LTSSM_ : CFG_LANENUM_ACCEPT => CFG_LANENUM_WAIT";
4515 move_to_cfg_lanenum_wait = 0;
4516 }
4517 break;
4518 }
4519 case CFG_LANENUM_WAIT :
4520 {
4521 cfg_lanenum_wait_counter++;
4522 if(move_to_cfg_lanenum_accept)
4523 {
4524 init_state = CFG_LANENUM_ACCEPT;
4525 csr_port.write_csr_mask(PEU_CSR_A_LNK_STS_HW_ADDR,(ILUPEU_LTSSM_CFG_LANENUM_ACEPT << PEU_CSR_CORE_STATUS_LTSSM_STATE_POSITION),PEU_CSR_CORE_STATUS_LTSSM_STATE_FMASK);
4526 link_field_is_PAD_ts1 = 0;
4527 link_field_is_PAD_ts2 = 0;
4528 lane_field_is_PAD_ts1 = 0;
4529 lane_field_is_PAD_ts2 = 0;
4530 link_field_is_non_PAD_ts1 = 0;
4531 lane_field_is_non_PAD_ts1 = 0;
4532 link_field_is_non_PAD_ts2 = 0;
4533 lane_field_is_non_PAD_ts2 = 0;
4534 transmitted_16xts2_sets = 0;
4535 ts1_count = 0;
4536 ts2_count = 0;
4537 LOG_INFO << "_LTSSM_ : CFG_LANENUM_WAIT => CFG_LANENUM_ACCEPT";
4538 from_cfg_lanenum_wait = true;
4539 cfg_lanenum_wait_counter = 0;
4540 }
4541 else if((link_field_is_PAD_ts1 >= 2 && lane_field_is_PAD_ts1 >= 2) || cfg_lanenum_wait_counter >= 100)
4542 {
4543 init_state = DETECT_QUIET;
4544 csr_port.write_csr_mask(PEU_CSR_A_CORE_STATUS_HW_ADDR,(ILUPEU_LTSSM_DETECT_QUIET << PEU_CSR_CORE_STATUS_LTSSM_STATE_POSITION),PEU_CSR_CORE_STATUS_LTSSM_STATE_FMASK);
4545 link_field_is_PAD_ts1 = 0;
4546 link_field_is_PAD_ts2 = 0;
4547 lane_field_is_PAD_ts1 = 0;
4548 lane_field_is_PAD_ts2 = 0;
4549 link_field_is_non_PAD_ts1 = 0;
4550 lane_field_is_non_PAD_ts1 = 0;
4551 link_field_is_non_PAD_ts2 = 0;
4552 lane_field_is_non_PAD_ts2 = 0;
4553 transmitted_16xts2_sets = 0;
4554 ts1_count = 0;
4555 ts2_count = 0;
4556 cfg_lanenum_wait_counter = 0;
4557
4558 // reset_var_detect_quiet();
4559 // cfg_lanenum_wait_counter = 0;
4560 LOG_INFO << "_LTSSM_ : CFG_LANENUM_WAIT => DETECT_QUIET";
4561 }
4562 break;
4563 }
4564 case CFG_COMPLETE :
4565 {
4566 cfg_complete_counter++;
4567 if((link_field_is_non_PAD_ts2 >= 8) && (lane_field_is_non_PAD_ts2 >= 8) && (transmitted_16xts2_sets))
4568 {
4569 init_state = CFG_IDLE;
4570 csr_port.write_csr_mask(PEU_CSR_A_LNK_STS_HW_ADDR,(ILUPEU_LTSSM_CFG_IDLE << PEU_CSR_CORE_STATUS_LTSSM_STATE_POSITION),PEU_CSR_CORE_STATUS_LTSSM_STATE_FMASK);
4571 link_field_is_PAD_ts1 = 0;
4572 link_field_is_PAD_ts2 = 0;
4573 lane_field_is_PAD_ts1 = 0;
4574 lane_field_is_PAD_ts2 = 0;
4575 link_field_is_non_PAD_ts1 = 0;
4576 lane_field_is_non_PAD_ts1 = 0;
4577 link_field_is_non_PAD_ts2 = 0;
4578 lane_field_is_non_PAD_ts2 = 0;
4579 transmitted_16xts2_sets = 0;
4580 ts1_count = 0;
4581 ts2_count = 0;
4582 received_1xts2_sets = 0;
4583 cfg_complete_counter = 0;
4584 LOG_INFO << " : _LTSSM_ : CFG_COMPLETE => CFG_IDLE";
4585
4586 }
4587 else if(cfg_complete_counter == CFG_COMPLETE_TIMEOUT)
4588 {
4589 init_state = DETECT_QUIET;
4590 csr_port.write_csr_mask(PEU_CSR_A_CORE_STATUS_HW_ADDR,(ILUPEU_LTSSM_DETECT_QUIET << PEU_CSR_CORE_STATUS_LTSSM_STATE_POSITION),PEU_CSR_CORE_STATUS_LTSSM_STATE_FMASK);
4591 link_field_is_PAD_ts1 = 0;
4592 link_field_is_PAD_ts2 = 0;
4593 lane_field_is_PAD_ts1 = 0;
4594 lane_field_is_PAD_ts2 = 0;
4595 transmitted_16xts2_sets = 0;
4596 ts1_count = 0;
4597 ts1_non_pad_link_bit = 0;
4598 ts2_count = 0;
4599 cfg_complete_counter = 0;
4600 elec_idle_pattern_bit = 0;
4601
4602 // reset_var_detect_quiet();
4603 // cfg_complete_counter = 0;
4604 LOG_INFO << " : _LTSSM_ : CFG_COMPLETE => DETECT_QUIET";
4605 }
4606 break;
4607 }
4608 case CFG_IDLE :
4609 {
4610 cfg_idle_counter++;
4611 if ( (received_8xidl_sets == 1) && transmitted_16xidl_sets)
4612 {
4613 init_state = L0;
4614 csr_port.write_csr_mask(PEU_CSR_A_CORE_STATUS_HW_ADDR,(ILUPEU_LTSSM_L0 << PEU_CSR_CORE_STATUS_LTSSM_STATE_POSITION),PEU_CSR_CORE_STATUS_LTSSM_STATE_FMASK);
4615 csr_port.write_csr_mask(PEU_CSR_A_LNK_STS_HW_ADDR,(PEU_CSR_LNK_STS_POR_VALUE << 11),PEU_CSR_LNK_STS_TRAIN_MASK);
4616 csr_port.write_csr_mask(PEU_CSR_A_LNK_STS_HW_ADDR,(LINK_WIDTH << 4),PEU_CSR_LNK_STS_WIDTH_MASK);
4617 csr_port.write_csr_mask(PEU_CSR_A_LNK_STS_HW_ADDR,(0x01 << 0),PEU_CSR_LNK_STS_SPEED_MASK);
4618
4619 link_field_is_PAD_ts1 = 0;
4620 link_field_is_PAD_ts2 = 0;
4621 lane_field_is_PAD_ts1 = 0;
4622 lane_field_is_PAD_ts2 = 0;
4623 transmitted_16xts2_sets = 0;
4624 ts1_count = 0;
4625 ts2_count = 0;
4626 received_8xts2_sets = 0;
4627 received_8xts1_sets = 0;
4628 received_8xidl_sets = 0;
4629 received_1xts2_sets = 0;
4630 received_1xts1_sets = 0;
4631 received_1xidl_sets = 0;
4632 ts1_2.range(159,0) = 0x0000000000000000000000000000000000000000;
4633 ts1_2_negedge.range(159,0) = 0x0000000000000000000000000000000000000000;
4634 electrical_idle_set.range(39,0) = 0x0000000000;
4635 electrical_idle_set_negedge.range(39,0) = 0x0000000000;
4636 skip_set.range(39,0) = 0x0000000000;
4637 skip_set_negedge.range(39,0) = 0x0000000000;
4638 cfg_idle_counter = 0;
4639 idl_count = 0;
4640 LOG_INFO << " : _LTSSM_ : CFG_IDLE => L0";
4641 }
4642 else if(cfg_idle_counter == CFG_IDLE_TIMEOUT)
4643 {
4644 init_state = DETECT_QUIET;
4645 csr_port.write_csr_mask(PEU_CSR_A_CORE_STATUS_HW_ADDR,(ILUPEU_LTSSM_DETECT_QUIET << PEU_CSR_CORE_STATUS_LTSSM_STATE_POSITION),PEU_CSR_CORE_STATUS_LTSSM_STATE_FMASK);
4646 link_field_is_PAD_ts1 = 0;
4647 link_field_is_PAD_ts2 = 0;
4648 lane_field_is_PAD_ts1 = 0;
4649 lane_field_is_PAD_ts2 = 0;
4650 link_field_is_non_PAD_ts1 = 0;
4651 lane_field_is_non_PAD_ts1 = 0;
4652 link_field_is_non_PAD_ts2 = 0;
4653 lane_field_is_non_PAD_ts2 = 0;
4654 transmitted_16xts2_sets = 0;
4655 ts1_count = 0;
4656 ts2_count = 0;
4657 cfg_idle_counter = 0;
4658 elec_idle_pattern_bit = 0;
4659 this_is_retraining = false;
4660 LOG_INFO << "_LTSSM_ : CFG_IDLE => DETECT_QUIET";
4661 // reset_var_detect_quiet();
4662 // cfg_idle_counter = 0;
4663 // this_is_retraining = false;
4664 }
4665 break;
4666 }
4667 case L0 :
4668 {
4669 if(!reset_l.read() || !reset_por_l.read())
4670 {
4671 init_state = DETECT_QUIET;
4672 init_state_rx = DETECT_QUIET;
4673 LOG_INFO << "_LTSSM_ : Going from L0 => DETECT_QUIET for reset_l or reset_por_l. However, last of the PL packets will still be processed";
4674 write_init_done = false;
4675 write_init_done_rx = false;
4676 init_done.write(false);
4677 init_done_rx.write(false);
4678 stage_init_state_rx = false;
4679 stage_init_state = true;
4680 csr_port.write_csr_mask(PEU_CSR_A_CORE_STATUS_HW_ADDR,(ILUPEU_LTSSM_DETECT_QUIET << PEU_CSR_CORE_STATUS_LTSSM_STATE_POSITION),PEU_CSR_CORE_STATUS_LTSSM_STATE_FMASK);
4681 link_field_is_PAD_ts1 = 0;
4682 link_field_is_PAD_ts2 = 0;
4683 lane_field_is_PAD_ts1 = 0;
4684 lane_field_is_PAD_ts2 = 0;
4685 ts1_count = 0;
4686 ts2_count = 0;
4687
4688 // reset_var_detect_quiet();
4689 ts1_2.range(159,0) = 0x0000000000000000000000000000000000000000;
4690 for(i=0;i<LINK_WIDTH;i++)
4691 ts1_2_serial[i].range(159,0) = 0x0000000000000000000000000000000000000000;
4692 last_idle_frame = false;
4693 done_last_idle = 0;
4694 }
4695 if(received_electrical_idle)
4696 {
4697 init_state = L0s;
4698 csr_port.write_csr_mask(PEU_CSR_A_CORE_STATUS_HW_ADDR,(ILUPEU_LTSSM_L0S << PEU_CSR_CORE_STATUS_LTSSM_STATE_POSITION),PEU_CSR_CORE_STATUS_LTSSM_STATE_FMASK);
4699 received_electrical_idle = 0;
4700 write_init_done = false;
4701 init_done.write(false);
4702 write_init_done_rx = false;
4703 init_done_rx.write(false);
4704 stage_init_state_rx = false;
4705 LOG_INFO << " _LTSSM_ : L0 => L0s";
4706 wait(SC_ZERO_TIME);
4707 }
4708 if(toRecovery || received_electrical_idle_constant_voltage)
4709 {
4710 init_state = Recovery_RcvrLock;
4711 init_state_rx = Recovery_RcvrLock;
4712 csr_port.write_csr_mask(PEU_CSR_A_CORE_STATUS_HW_ADDR,(ILUPEU_LTSSM_RCVRY_RCVRLOCK << PEU_CSR_CORE_STATUS_LTSSM_STATE_POSITION),PEU_CSR_CORE_STATUS_LTSSM_STATE_FMASK);
4713 LOG_INFO << " : _LTSSM_ : L0 => Recovery_RcvrLock. However, last of the PL packets will still be processed.";
4714
4715
4716 write_init_done = false;
4717 init_done.write(false);
4718 write_init_done_rx = false;
4719 stage_init_state = true;
4720 init_done_rx.write(false);
4721 stage_init_state_rx = false;
4722 toRecovery = false;
4723 received_electrical_idle = false;
4724 ts1_non_pad_lane_bit = 0;
4725 electrical_idle_constant_voltage_set = 0x3ff;
4726 ts1_non_pad_link_bit = 0;
4727 ts1_non_pad_link_lane = 0;
4728 ts2_pattern_bit = 0;
4729 ts2_failover_pattern_bit = 0;
4730 idle_pattern_bit = 0;
4731 idl_count = 0;
4732 transmitted_idl_pattern = 0;
4733 transmitted_16xidl_sets = 0;
4734 retraining = true;
4735 this_is_retraining = true;
4736 done_last_idle_retrain = 0;
4737 link_field_is_non_PAD_ts1 = 0;
4738 lane_field_is_non_PAD_ts1 = 0;
4739 link_field_is_non_PAD_ts2 = 0;
4740 lane_field_is_non_PAD_ts2 = 0;
4741 first_retrain_idle_detection = true;
4742 ts1_2.range(159,0) = 0x0000000000000000000000000000000000000000;
4743 for(i=0;i<LINK_WIDTH;i++)
4744 ts1_2_serial[i].range(159,0) = 0x0000000000000000000000000000000000000000;
4745 }
4746 break;
4747 }
4748 case Recovery_RcvrLock :
4749 {
4750 RcvrLock_counter++;
4751 if((link_field_is_non_PAD_ts1 >= 8 || link_field_is_non_PAD_ts2 >= 8) && (lane_field_is_non_PAD_ts1 >= 8 || lane_field_is_non_PAD_ts2 >= 8))
4752 {
4753 init_state = Recovery_RcvrCfg;
4754 csr_port.write_csr_mask(PEU_CSR_A_CORE_STATUS_HW_ADDR,(ILUPEU_LTSSM_RCVRY_RCVRCFG << PEU_CSR_CORE_STATUS_LTSSM_STATE_POSITION),PEU_CSR_CORE_STATUS_LTSSM_STATE_FMASK);
4755 RcvrLock_counter = 0;
4756 LOG_INFO << "_LTSSM_ : Recovery_RcvrLock => Recovery_RcvrCfg";
4757 constant_voltage_count = 0;
4758 }
4759 if(RcvrLock_counter == Recovery_RcvrLock_TIMEOUT) // Timeout
4760 {
4761 if((link_field_is_non_PAD_ts1 > 0 || link_field_is_non_PAD_ts2 > 0) && (lane_field_is_non_PAD_ts1 > 0 || lane_field_is_non_PAD_ts2 > 0))
4762 {
4763 init_state = CFG_LINKWIDTH_START;
4764 csr_port.write_csr_mask(PEU_CSR_A_CORE_STATUS_HW_ADDR,(ILUPEU_LTSSM_CFG_LINKWD_START << PEU_CSR_CORE_STATUS_LTSSM_STATE_POSITION),PEU_CSR_CORE_STATUS_LTSSM_STATE_FMASK);
4765 RcvrLock_counter = 0;
4766 LOG_INFO << "_LTSSM_ : Recovery_RcvrLock => CFG_LINKWIDTH_START";
4767 }
4768 else
4769 {
4770 init_state = DETECT_QUIET;
4771 link_field_is_PAD_ts1 = 0;
4772 link_field_is_PAD_ts2 = 0;
4773 lane_field_is_PAD_ts1 = 0;
4774 lane_field_is_PAD_ts2 = 0;
4775 link_field_is_non_PAD_ts1 = 0;
4776 lane_field_is_non_PAD_ts1 = 0;
4777 link_field_is_non_PAD_ts2 = 0;
4778 lane_field_is_non_PAD_ts2 = 0;
4779 transmitted_16xts2_sets = 0;
4780 ts1_count = 0;
4781 constant_voltage_count = 0;
4782 ts2_count = 0;
4783 symbol_num = 0;
4784 ts1_non_pad_link_bit = 0;
4785 elec_idle_pattern_bit = 0;
4786 // reset_var_detect_quiet();
4787 csr_port.write_csr_mask(PEU_CSR_A_CORE_STATUS_HW_ADDR,(ILUPEU_LTSSM_DETECT_QUIET << PEU_CSR_CORE_STATUS_LTSSM_STATE_POSITION),PEU_CSR_CORE_STATUS_LTSSM_STATE_FMASK);
4788 if(received_electrical_idle_constant_voltage)
4789 {
4790 LOG_INFO << "LTSSM: Detected electrical idle constant voltage, entering drain state..." ;
4791 //csr_port.write_csr_mask(PEU_CSR_A_TLU_STS_HW_ADDR,(0x1 << 8),PEU_CSR_TLU_STS_SET_MASK);
4792 enter_drain_state = true;
4793 csr_port.write_csr_mask(PEU_CSR_A_OE_ERR_RW1S_ALIAS_HW_ADDR,(0x1 << 9),PEU_CSR_OE_ERR_RW1S_ALIAS_SET_MASK);
4794 csr_port.write_csr_mask(PEU_CSR_A_LNK_STS_HW_ADDR,(0x0 << 4),PEU_CSR_LNK_STS_WIDTH_MASK);
4795 csr_port.write_csr_mask(PEU_CSR_A_LNK_STS_HW_ADDR,(0x00 << 0),PEU_CSR_LNK_STS_SPEED_MASK);
4796 }
4797 csr_port.write_csr_mask(PEU_CSR_A_LNK_STS_HW_ADDR,(0x0 << 4),PEU_CSR_LNK_STS_WIDTH_MASK);
4798 csr_port.write_csr_mask(PEU_CSR_A_LNK_STS_HW_ADDR,(0x00 << 0),PEU_CSR_LNK_STS_SPEED_MASK);
4799 RcvrLock_counter = 0;
4800 LOG_INFO << "_LTSSM_ : Timeout : Recovery_RcvrLock => DETECT_QUIET";
4801 }
4802 }
4803 break;
4804 }
4805 case Recovery_RcvrCfg :
4806 {
4807 RcvrCfg_counter++;
4808
4809 if((link_field_is_non_PAD_ts2 >= 8) && (lane_field_is_non_PAD_ts2 >= 8) && (transmitted_16xts2_sets))
4810 {
4811 init_state = Recovery_Idle;
4812 csr_port.write_csr_mask(PEU_CSR_A_CORE_STATUS_HW_ADDR,(ILUPEU_LTSSM_RCVRY_IDLE << PEU_CSR_CORE_STATUS_LTSSM_STATE_POSITION),PEU_CSR_CORE_STATUS_LTSSM_STATE_FMASK);
4813 RcvrCfg_counter = 0;
4814 LOG_INFO << "_LTSSM_ : Recovery_RcvrCfg => Recovery_Idle";
4815 constant_voltage_count = 0;
4816 transmitted_16xts2_sets = 0;
4817 }
4818 if(RcvrCfg_counter == Recovery_RcvrCfg_TIMEOUT)
4819 {
4820 init_state = DETECT_QUIET;
4821 link_field_is_PAD_ts1 = 0;
4822 link_field_is_PAD_ts2 = 0;
4823 lane_field_is_PAD_ts1 = 0;
4824 lane_field_is_PAD_ts2 = 0;
4825 link_field_is_non_PAD_ts1 = 0;
4826 lane_field_is_non_PAD_ts1 = 0;
4827 link_field_is_non_PAD_ts2 = 0;
4828 lane_field_is_non_PAD_ts2 = 0;
4829 transmitted_16xts2_sets = 0;
4830 ts1_count = 0;
4831 ts2_count = 0;
4832 symbol_num = 0;
4833 ts1_non_pad_link_bit = 0;
4834
4835 // reset_var_detect_quiet();
4836 csr_port.write_csr_mask(PEU_CSR_A_CORE_STATUS_HW_ADDR,(ILUPEU_LTSSM_DETECT_QUIET << PEU_CSR_CORE_STATUS_LTSSM_STATE_POSITION),PEU_CSR_CORE_STATUS_LTSSM_STATE_FMASK);
4837
4838 RcvrCfg_counter = 0;
4839 elec_idle_pattern_bit = 0;
4840 LOG_INFO << "_LTSSM_ : Timeout : Recovery_RcvrCfg => DETECT_QUIET";
4841 }
4842 break;
4843 }
4844 case Recovery_Idle :
4845 {
4846 RcvrIdle_counter++;
4847 if(macl_pcs_ctl_csr.range(0,0) == 0x1) // Enter HOT_RESET0
4848 {
4849 init_state = HOT_RESET0;
4850 LOG_INFO << "_LTSSM_ : Preparing to Enter Hot Reset";
4851 csr_port.write_csr_mask(PEU_CSR_A_CORE_STATUS_HW_ADDR,(ILUPEU_LTSSM_HOT_RESET_ENTRY << PEU_CSR_CORE_STATUS_LTSSM_STATE_POSITION),PEU_CSR_CORE_STATUS_LTSSM_STATE_FMASK);
4852 link_field_is_non_PAD_ts1 = 0;
4853 lane_field_is_non_PAD_ts1 = 0;
4854 link_field_is_non_PAD_ts2 = 0;
4855 lane_field_is_non_PAD_ts2 = 0;
4856 transmitted_16xidl_sets = 0;
4857 // No CSR write yet
4858 }
4859 if ( (received_8xidl_sets == 1) && transmitted_16xidl_sets)
4860 {
4861 init_state = L0;
4862 csr_port.write_csr_mask(PEU_CSR_A_CORE_STATUS_HW_ADDR,(ILUPEU_LTSSM_L0 << PEU_CSR_CORE_STATUS_LTSSM_STATE_POSITION),PEU_CSR_CORE_STATUS_LTSSM_STATE_FMASK);
4863 cout << "Bringing up the link..." << endl;
4864 csr_port.write_csr_mask(PEU_CSR_A_OE_ERR_RW1S_ALIAS_HW_ADDR,(0x0 << 9),PEU_CSR_OE_ERR_RW1S_ALIAS_SET_MASK);
4865 csr_port.write_csr_mask(PEU_CSR_A_LNK_STS_HW_ADDR,(PEU_CSR_LNK_STS_POR_VALUE << 11),PEU_CSR_LNK_STS_TRAIN_MASK);
4866 csr_port.write_csr_mask(PEU_CSR_A_LNK_STS_HW_ADDR,(LINK_WIDTH << 4),PEU_CSR_LNK_STS_WIDTH_MASK);
4867 csr_port.write_csr_mask(PEU_CSR_A_LNK_STS_HW_ADDR,(0x01 << 0),PEU_CSR_LNK_STS_SPEED_MASK);
4868 link_field_is_PAD_ts1 = 0;
4869 link_field_is_PAD_ts2 = 0;
4870 lane_field_is_PAD_ts1 = 0;
4871 lane_field_is_PAD_ts2 = 0;
4872 transmitted_16xts2_sets = 0;
4873 ts1_count = 0;
4874 ts2_count = 0;
4875 received_8xts2_sets = 0;
4876 received_8xts1_sets = 0;
4877 received_8xidl_sets = 0;
4878 received_1xts2_sets = 0;
4879 received_1xts1_sets = 0;
4880 electrical_idle_constant_voltage_set = 0x3ff;
4881 received_electrical_idle_constant_voltage = false;
4882 RcvrIdle_counter = 0;
4883 LOG_INFO << "_LTSSM_ : Recovery_Idle => L0";
4884 }
4885 if(RcvrIdle_counter == Recovery_Idle_TIMEOUT)
4886 {
4887 init_state = DETECT_QUIET;
4888 link_field_is_PAD_ts1 = 0;
4889 link_field_is_PAD_ts2 = 0;
4890 lane_field_is_PAD_ts1 = 0;
4891 lane_field_is_PAD_ts2 = 0;
4892 link_field_is_non_PAD_ts1 = 0;
4893 lane_field_is_non_PAD_ts1 = 0;
4894 link_field_is_non_PAD_ts2 = 0;
4895 lane_field_is_non_PAD_ts2 = 0;
4896 transmitted_16xts2_sets = 0;
4897 ts1_count = 0;
4898 ts2_count = 0;
4899 symbol_num = 0;
4900 ts1_non_pad_link_bit = 0;
4901 elec_idle_pattern_bit = 0;
4902
4903 // reset_var_detect_quiet();
4904 csr_port.write_csr_mask(PEU_CSR_A_CORE_STATUS_HW_ADDR,(ILUPEU_LTSSM_DETECT_QUIET << PEU_CSR_CORE_STATUS_LTSSM_STATE_POSITION),PEU_CSR_CORE_STATUS_LTSSM_STATE_FMASK);
4905 RcvrIdle_counter = 0;
4906 LOG_INFO << "_LTSSM_ : Recovery_Idle => DETECT_QUIET";
4907 }
4908 break;
4909 }
4910 case HOT_RESET0 :
4911 {
4912 if(received_2xts1_hot_reset)
4913 {
4914 init_state = HOT_RESET;
4915 csr_port.write_csr_mask(PEU_CSR_A_CORE_STATUS_HW_ADDR,(ILUPEU_LTSSM_HOT_RESET << PEU_CSR_CORE_STATUS_LTSSM_STATE_POSITION),PEU_CSR_CORE_STATUS_LTSSM_STATE_FMASK);
4916 LOG_INFO << "_LTSSM_ : Recovery_Idle => HOT_RESET";
4917 }
4918 break;
4919 }
4920 case HOT_RESET :
4921 {
4922 hot_reset_counter++;
4923 if(hot_reset_counter == HOT_RESET_TIMEOUT)
4924 {
4925 hot_reset_counter = 0;
4926 init_state = DETECT_QUIET;
4927 LOG_INFO << "_LTSSM_ : Auto Timing Out from HOT_RESET => DETECT_QUIET";
4928 csr_port.write_csr_mask(PEU_CSR_A_CORE_STATUS_HW_ADDR,(ILUPEU_LTSSM_DETECT_QUIET << PEU_CSR_CORE_STATUS_LTSSM_STATE_POSITION),PEU_CSR_CORE_STATUS_LTSSM_STATE_FMASK);
4929 csr_port.write_csr_mask(PEU_CSR_A_LINK_CTL_HW_ADDR,(0x0 << 0),PEU_CSR_MACL_PCS_RESET_FMASK); // Bring down this csr
4930 //Bringing down the link, setting link reset and resetting the link speed and width
4931 csr_port.write_csr_mask(PEU_CSR_A_OE_ERR_RW1S_ALIAS_HW_ADDR,(0x1 << 9),PEU_CSR_OE_ERR_RW1C_ALIAS_SET_MASK);
4932 sc_uint<64> temp=0; temp.range(42,42)=1;
4933 csr_port.write_csr_mask(PEU_CSR_A_OE_ERR_RW1S_ALIAS_HW_ADDR,temp,PEU_CSR_OE_ERR_RW1C_ALIAS_SET_MASK);
4934 csr_port.write_csr_mask(PEU_CSR_A_LNK_STS_HW_ADDR,(0x0 << 4),PEU_CSR_LNK_STS_WIDTH_MASK);
4935 csr_port.write_csr_mask(PEU_CSR_A_LNK_STS_HW_ADDR,(0x00 << 0),PEU_CSR_LNK_STS_SPEED_MASK);
4936
4937 link_field_is_PAD_ts1 = 0;
4938 link_field_is_PAD_ts2 = 0;
4939 lane_field_is_PAD_ts1 = 0;
4940 lane_field_is_PAD_ts2 = 0;
4941 link_field_is_non_PAD_ts1 = 0;
4942 lane_field_is_non_PAD_ts1 = 0;
4943 link_field_is_non_PAD_ts2 = 0;
4944 lane_field_is_non_PAD_ts2 = 0;
4945 transmitted_16xts2_sets = 0;
4946 received_8xts2_sets = 0;
4947 received_8xts1_sets = 0;
4948 received_8xidl_sets = 0;
4949 received_1xts2_sets = 0;
4950 received_1xts1_sets = 0;
4951 received_1xidl_sets = 0;
4952 ts1_count = 0;
4953 ts2_count = 0;
4954 symbol_num = 0;
4955 ts1_non_pad_link_bit = 0;
4956 elec_idle_pattern_bit = 0;
4957 received_2xts1_hot_reset = false;
4958
4959 // reset_var_detect_quiet();
4960 ts1_hot_reset_count = 0;
4961 }
4962 break;
4963 }
4964 case L0s :
4965 {
4966 if(received_skp_ordered_set)
4967 {
4968 init_state = L0;
4969 csr_port.write_csr_mask(PEU_CSR_A_CORE_STATUS_HW_ADDR,(ILUPEU_LTSSM_L0 << PEU_CSR_CORE_STATUS_LTSSM_STATE_POSITION),PEU_CSR_CORE_STATUS_LTSSM_STATE_FMASK);
4970 csr_port.write_csr_mask(PEU_CSR_A_LNK_STS_HW_ADDR,(PEU_CSR_LNK_STS_POR_VALUE << 11),PEU_CSR_LNK_STS_TRAIN_MASK);
4971 received_skp_ordered_set = 0;
4972 LOG_INFO << "_LTSSM_ : L0s => L0";
4973 }
4974 break;
4975 }
4976 /// For future implementation
4977 case L1 :
4978 {
4979 break;
4980 }
4981 /// For future implementation
4982 case L2 :
4983 {
4984 break;
4985 }
4986 /// For future implementation
4987 case DISABLE :
4988 {
4989 break;
4990 }
4991 /// For future implementation
4992 case LOOPBACK :
4993 {
4994 break;
4995 }
4996 }
4997 }
4998 if(!(reset_l.read()) || !(reset_por_l.read()))
4999 {
5000 init_state = DETECT_QUIET;
5001 LOG_INFO << "_LTSSM_ : Going to DETECT_QUIET due to reset";
5002 }
5003
5004 if((init_state == DETECT_QUIET) || (init_state == DETECT_ACTIVE))
5005 {
5006 for(i=0;i<20;i++)
5007 wait(frame_boundary_reg_tx.negedge_event());
5008 }
5009 else
5010 {
5011 wait(frame_boundary_reg_tx.negedge_event());
5012 }
5013 }
5014}
5015
5016/// Sets the init_state_rx variable
5017void ltssm::init_state_machine_rx()
5018{
5019 while(true)
5020 {
5021 init_state_rx = init_state;
5022 wait(frame_boundary_reg.negedge_event());
5023 }
5024}