OpenCores
URL https://opencores.org/ocsvn/ht_tunnel/ht_tunnel/trunk

Subversion Repositories ht_tunnel

[/] [ht_tunnel/] [trunk/] [rtl/] [systemc/] [flow_control_l2/] [flow_control_l3.cpp] - Blame information for rev 19

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 acastong
//flow_control_l3.cpp
2
 
3
/* ***** BEGIN LICENSE BLOCK *****
4
 * Version: MPL 1.1
5
 *
6
 * The contents of this file are subject to the Mozilla Public License Version
7
 * 1.1 (the "License"); you may not use this file except in compliance with
8
 * the License. You may obtain a copy of the License at
9
 * http://www.mozilla.org/MPL/
10
 *
11
 * Software distributed under the License is distributed on an "AS IS" basis,
12
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13
 * for the specific language governing rights and limitations under the
14
 * License.
15
 *
16
 * The Original Code is HyperTransport Tunnel IP Core.
17
 *
18
 * The Initial Developer of the Original Code is
19
 * Ecole Polytechnique de Montreal.
20
 * Portions created by the Initial Developer are Copyright (C) 2005
21
 * the Initial Developer. All Rights Reserved.
22
 *
23
 * Contributor(s):
24
 *   Jean-Francois Belanger
25
 *   Ami Castonguay <acastong@grm.polymtl.ca>
26
 *
27
 * Alternatively, the contents of this file may be used under the terms
28
 * of the Polytechnique HyperTransport Tunnel IP Core Source Code License
29
 * (the  "PHTICSCL License", see the file PHTICSCL.txt), in which case the
30
 * provisions of PHTICSCL License are applicable instead of those
31
 * above. If you wish to allow use of your version of this file only
32
 * under the terms of the PHTICSCL License and not to allow others to use
33
 * your version of this file under the MPL, indicate your decision by
34
 * deleting the provisions above and replace them with the notice and
35
 * other provisions required by the PHTICSCL License. If you do not delete
36
 * the provisions above, a recipient may use your version of this file
37
 * under either the MPL or the PHTICSCL License."
38
 *
39
 * ***** END LICENSE BLOCK ***** */
40
 
41
#include "flow_control_l3.h"
42
 
43
flow_control_l3::flow_control_l3(sc_module_name name) : sc_module(name)
44
{
45
        /** Processes of the design.  The sensitivity list is in function
46
                of what theses processes uses.*/
47
 
48
        SC_METHOD(fc_fsm_state);
49
                sensitive_pos << clock;
50
                sensitive_neg << resetx;
51
 
52
        SC_METHOD(fc_fsm);
53
                sensitive  << curr_state << fifo_user_available
54
                        << ro_available_fwd << ro_nop_req_fc << db_nop_req_fc
55
                        <<  has_nop_buffers_to_send
56
                        << fc_data_vc_ui
57
                        << resetx
58
 
59
                        << fifo_user_packet << fifo_user_available
60
                        << eh_cmd_data_fc << eh_available_fc
61
                        << csr_dword_fc << csr_available_fc
62
                        << ro_packet_fwd << ro_available_fwd
63
 
64
                        << data_cnt << has_data << ldtstopx  << chain_current_state
65
                        << fwd_next_node_buffer_status_ro
66
                        << nop_next_to_send << lk_consume_fc
67
                        << found_next_state
68
                        << found_load_fwd_pkt
69
                        << found_load_eh_pkt
70
                        << found_load_csr_pkt
71
                        << found_load_user_fifo_pkt
72
                        << found_next_chain_current_state
73
                        << found_fc_ctr_mux
74
                        << found_fc_nop_sent
75
                        << found_generate_disconnect_nop
76
                        << found_next_data_cnt
77
                        << found_next_has_data
78
                        << found_current_sent_type
79
                        << buffered_fwd_vctype_db
80
                        << found_fwd_vctype_db
81
                        << buffered_fwd_address_db
82
                        << found_fwd_address_db
83
                        << buffered_fc_data_vc_ui
84
                        << found_fc_data_vc_ui
85
                        << found_local_packet_issued
86
                        << found_next_fairness_vc_reserved[0] << found_next_fairness_vc_reserved[1] << found_next_fairness_vc_reserved[2]
87
 
88
                        << registered_lk_initiate_retry_disconnect
89
                        << found_hold_user_fifo_pkt
90
                        << fc_lctl_lk << fc_hctl_lk
91
 
92
#ifdef RETRY_MODE_ENABLED
93
                        << registered_lk_rx_connected
94
                        << received_ack
95
                        << found_new_history_entry_size_m1
96
                        << found_new_history_entry
97
                        << new_history_entry_size_m1
98
                        << retry_disconnect_initiated<< cd_initiate_retry_disconnect
99
                        << history_playback_done << history_packet
100
                        << csr_retry
101
 
102
                        << foundh_fc_ctr_mux << foundh_fc_nop_sent << foundh_next_state
103
                        << foundh_next_fc_lctl_lk << foundh_next_fc_hctl_lk << foundh_next_calculate_nop_crc
104
                        << foundh_next_calculate_crc << foundh_next_data_cnt << foundh_next_has_data
105
                        << foundh_current_sent_type << foundh_consume_history
106
#endif
107
                        ;
108
 
109
        SC_METHOD(find_next_state);
110
        sensitive << ro_nop_req_fc << db_nop_req_fc << nop_next_to_send
111
                << ldtstopx
112
                << csr_dword_fc
113
                << csr_available_fc
114
                << fwd_next_node_buffer_status_ro << eh_cmd_data_fc
115
                << fifo_user_packet << eh_available_fc << fifo_user_available
116
                << ro_packet_fwd << ro_available_fwd
117
                << local_priority
118
                << fairness_vc_reserved[0] << fairness_vc_reserved[1] << fairness_vc_reserved[2]
119
                << fc_data_vc_ui
120
                << buffered_fwd_vctype_db << buffered_fwd_address_db
121
#ifdef RETRY_MODE_ENABLED
122
                << csr_retry
123
                << room_available_in_history
124
                << cd_initiate_retry_disconnect
125
                << retry_disconnect_initiated
126
#endif
127
                ;
128
#ifdef RETRY_MODE_ENABLED
129
        SC_METHOD(find_next_retry_state);
130
        sensitive << ro_nop_req_fc << db_nop_req_fc << nop_next_to_send
131
                << ldtstopx << fwd_next_node_buffer_status_ro << history_packet
132
                << history_playback_done << foundh_generate_disconnect_nop;
133
 
134
#endif
135
}
136
 
137
void flow_control_l3::fc_fsm_state( void )
138
{
139
 
140
        //Upon the reset signal, go to the RESET_STATE and clear any chain state
141
        if (resetx == false) {
142
                curr_state.write(NOP_SENT);
143
                chain_current_state = NO_CHAIN_STATE;
144
 
145
                fc_lctl_lk = true;
146
                fc_hctl_lk = true;
147
 
148
#ifdef RETRY_MODE_ENABLED
149
                received_ack = false;
150
                fc_disconnect_lk = false;
151
                registered_lk_rx_connected = false;
152
                registered_lk_initiate_retry_disconnect = false;
153
                retry_disconnect_initiated = false;
154
 
155
                select_crc_output = false;
156
                select_nop_crc_output = false;
157
 
158
                //We start with a nop, so calculate CRC
159
                calculate_nop_crc = true;
160
                calculate_crc = false;
161
#endif
162
 
163
                buffered_fc_data_vc_ui = VC_NONE;
164
                buffered_fwd_address_db = 0;
165
                buffered_fwd_vctype_db = VC_NONE;
166
 
167
                data_cnt = 0;
168
                has_data = false;
169
 
170
                for(int n = 0; n < 3; n++)
171
                        fairness_vc_reserved[n] = false;
172
 
173
        }
174
        //Otherwise, store the next value
175
        else {
176
                curr_state.write(next_state.read());
177
 
178
#ifdef RETRY_MODE_ENABLED
179
                fc_disconnect_lk = next_fc_disconnect_lk;
180
                registered_lk_rx_connected = lk_rx_connected;
181
                registered_lk_initiate_retry_disconnect = lk_initiate_retry_disconnect;
182
#endif
183
                chain_current_state = next_chain_current_state;
184
 
185
                fc_lctl_lk = next_fc_lctl_lk;
186
                fc_hctl_lk = next_fc_hctl_lk;
187
 
188
#ifdef RETRY_MODE_ENABLED
189
                /**It might not be possible to start a retry a retry sequence
190
                immediately after we receive a signal to initiate it, so store
191
                that a retry sequence was initiated and clear it later when we
192
                take it into account*/
193
                if(clear_retry_disconnect_initiated){
194
                        retry_disconnect_initiated = false;
195
                }
196
                else if(cd_initiate_retry_disconnect.read() ||
197
                                registered_lk_initiate_retry_disconnect.read())
198
                        retry_disconnect_initiated = true;
199
                else
200
                        retry_disconnect_initiated = retry_disconnect_initiated.read();
201
 
202
                /**
203
                        When we are in retry mode, we want to wait until we have received
204
                        at least a single ack that represents the last good packet they
205
                        received, so that we know when to replay the history.  received_ack
206
                        keeps track if we have received that first ack
207
                */
208
                if(lk_rx_connected == false)
209
                        received_ack = false;
210
                else if(nop_received == true)
211
                        received_ack = true;
212
                else
213
                        received_ack = received_ack.read();
214
 
215
                select_crc_output = next_select_crc_output;
216
                select_nop_crc_output = next_select_nop_crc_output;
217
 
218
                calculate_nop_crc = next_calculate_nop_crc;
219
                calculate_crc = next_calculate_crc;
220
 
221
#endif
222
 
223
                buffered_fc_data_vc_ui = fc_data_vc_ui.read();
224
                buffered_fwd_address_db = fwd_address_db.read();
225
                buffered_fwd_vctype_db = fwd_vctype_db;
226
 
227
                data_cnt = next_data_cnt;
228
                has_data = next_has_data;
229
 
230
                for(int n = 0; n < 3; n++)
231
                        fairness_vc_reserved[n] = next_fairness_vc_reserved[n];
232
        }
233
}
234
 
235
 
236
void flow_control_l3::fc_fsm( void ){
237
        // test to know if a nop request is present
238
        bool nop_req;
239
        if (ro_nop_req_fc ==  true || db_nop_req_fc ==  true || nop_next_to_send == true )
240
                nop_req = true;
241
        else
242
                nop_req  = false;
243
 
244
        //far_end buffer status
245
        sc_bv<6> buffer_status_tmp = fwd_next_node_buffer_status_ro;
246
 
247
        //variable who contain the status for response. useful to know quickly if a CSR
248
        //or EH can be send
249
        sc_bv<2> far_end_resp_stat = (buffer_status_tmp[0],buffer_status_tmp[1]);
250
 
251
        //control  of the multiplexer
252
        fc_ctr_mux = FC_MUX_FEEDBACK;
253
        //variable indicating that a nop is currently send
254
        fc_nop_sent = false;
255
        // variable indicating the amount of data remaining for a sequence
256
        next_data_cnt = data_cnt;
257
        // Indicate a data packet consonmmation to the data buffer
258
        fwd_read_db = false;
259
        //Erase a data packet from the buffers
260
        fwd_erase_db = false;
261
        // indicate a data packet consonmmation to the user buffer
262
        fc_consume_data_ui = false;
263
 
264
        //acknowledges
265
        fwd_ack_ro = false;
266
        consume_user_fifo = false;
267
        fc_ack_eh = false;
268
        fc_ack_csr = false;
269
 
270
        //Hold the packet so it doesn't change after sending the first dword
271
        hold_user_fifo = false;
272
 
273
#ifdef RETRY_MODE_ENABLED
274
        //History
275
        begin_history_playback = false;
276
        stop_history_playback = false;
277
        consume_history = false;
278
        add_to_history = false;
279
        new_history_entry = false;
280
        new_history_entry_size_m1 = 0;
281
 
282
        //Per-packet crc
283
        clear_crc = false;
284
        clear_nop_crc = false;
285
 
286
        // ctl signal, in reset it have no meaning
287
        next_fc_disconnect_lk = false;
288
 
289
        //Some other default outputs
290
        clear_farend_count = false;
291
 
292
        next_select_crc_output = false;
293
        next_select_nop_crc_output = false;
294
        clear_retry_disconnect_initiated = false;
295
#endif
296
 
297
        //When this is true, the nop framer will produce a disconnect nop
298
        generate_disconnect_nop = false;
299
 
300
 
301
        //Default, not sending anything
302
        current_sent_type = "000000";
303
 
304
 
305
        next_chain_current_state = chain_current_state;
306
 
307
        //By default, keep sending the same VC on the output
308
        fc_data_vc_ui = buffered_fc_data_vc_ui.read();
309
        fwd_vctype_db = buffered_fwd_vctype_db.read();
310
        fwd_address_db = buffered_fwd_address_db.read();
311
 
312
        //For the  fairness algorithm
313
        local_packet_issued = false;
314
        for(int n = 0; n < 3; n++)
315
                next_fairness_vc_reserved[n] = fairness_vc_reserved[n];
316
 
317
        next_state = curr_state.read();
318
 
319
        next_fc_lctl_lk = true;
320
        next_fc_hctl_lk = true;
321
        next_has_data = has_data.read();
322
 
323
        //By default, don't calculate any CRC
324
#ifdef RETRY_MODE_ENABLED
325
        next_calculate_crc = false;
326
        next_calculate_nop_crc = false;
327
#endif
328
 
329
        /**
330
                Select what to do and output in functino of our present state
331
        */
332
        switch (curr_state.read()) {
333
        //State that sends nop
334
 
335
        case FWD_CMD32_SENT:
336
                {
337
#ifdef RETRY_MODE_ENABLED
338
                        add_to_history = lk_consume_fc.read();
339
#endif
340
                        //If output not consumed, don't modify the output
341
                        if(!lk_consume_fc.read()){
342
                                next_state = FWD_CMD32_SENT;
343
                                next_fc_lctl_lk = true;
344
                                next_fc_hctl_lk = true;
345
                        }
346
                        //If there is data with this packet
347
                        else if (has_data.read()){
348
                                //If a request for nop, interrupt sending the data to send nop
349
                                if (nop_req == true){
350
                                        go_NOP_SENT_IN_FWD();
351
                                }
352
                                //Otherwise go send the data
353
                                else{
354
                                        go_FWD_DATA_SENT();
355
                                }
356
                        }
357
#ifdef RETRY_MODE_ENABLED
358
                        //If no data and in retry mode, send the per-packet CRC
359
                        else if(csr_retry.read()){
360
                                go_SEND_CMD_CRC();
361
                        }
362
#endif
363
                        //No data and no retry mode means packet sent : find next packet to send
364
                        else{
365
                                set_next_state();
366
                        }
367
                }
368
                break;
369
 
370
        case FWD_CMD64_FIRST_SENT:
371
                {
372
#ifdef RETRY_MODE_ENABLED
373
                        add_to_history = lk_consume_fc.read();
374
#endif
375
 
376
                        //If output not consumed, don't modify the output
377
                        if(!lk_consume_fc.read()){
378
                                next_state = FWD_CMD64_FIRST_SENT;
379
                                next_fc_lctl_lk = true;
380
                                next_fc_hctl_lk = true;
381
                        }
382
                        //Go send the second dword
383
                        else{
384
                                next_state = FWD_CMD64_SECOND_SENT;
385
                                fc_ctr_mux = FC_MUX_FWD_MSB; //32 bits lsb FWD_CMD
386
                                next_fc_lctl_lk = true;
387
                                next_fc_hctl_lk = true;
388
                                fwd_ack_ro = true;
389
#ifdef RETRY_MODE_ENABLED
390
                                next_calculate_crc = true;
391
                                add_to_history = true;
392
#endif
393
                        }
394
                }
395
                break;
396
        case FWD_CMD64_SECOND_SENT:
397
 
398
#ifdef RETRY_MODE_ENABLED
399
                add_to_history = lk_consume_fc.read();
400
#endif
401
 
402
                //If output not consumed, don't modify the output
403
                if(!lk_consume_fc.read()){
404
                        next_state = FWD_CMD64_SECOND_SENT;
405
                        next_fc_lctl_lk = true;
406
                        next_fc_hctl_lk = true;
407
                }
408
                //If there is data with this packet
409
                else if (has_data.read()){
410
                        //If a request for nop, interrupt sending the data to send nop
411
                        if (nop_req == true)
412
                                go_NOP_SENT_IN_FWD();
413
                        //Otherwise go send the data
414
                        else{
415
                                go_FWD_DATA_SENT();
416
                        }
417
                }
418
#ifdef RETRY_MODE_ENABLED
419
                //If no data and in retry mode, send the per-packet CRC
420
                else if(csr_retry.read()){
421
                        go_SEND_CMD_CRC();
422
                }
423
#endif
424
                //No data and no retry mode means packet sent : find next packet to send
425
                else {
426
                        set_next_state();
427
                }
428
                break;
429
 
430
        case FWD_DATA_SENT:
431
                //cout << "entering FWD_DATA_SENT" <<endl;      
432
 
433
#ifdef RETRY_MODE_ENABLED
434
                add_to_history = lk_consume_fc.read();
435
#endif
436
 
437
                //If output not consumed, don't modify the output
438
                if(!lk_consume_fc.read()){
439
                        next_state = FWD_DATA_SENT;
440
                        next_fc_lctl_lk = false;
441
                        next_fc_hctl_lk = false;
442
                }
443
                //If there is data left to send
444
                else if (has_data.read()){
445
                        //If a request for nop, interrupt sending the data to send nop
446
                        if (nop_req == true)
447
                                go_NOP_SENT_IN_FWD();
448
                        //Otherwise keep sending data
449
                        else
450
                                go_FWD_DATA_SENT();
451
                }
452
#ifdef RETRY_MODE_ENABLED
453
                else if(csr_retry.read()){
454
                        go_SEND_DATA_CRC();
455
                }
456
#endif
457
                //No data and no retry mode means packet sent : find next packet to send
458
                else {
459
                        set_next_state();
460
                }
461
                break;
462
 
463
        case NOP_SENT_IN_FWD:
464
 
465
                //cout << "entering fc_nop_sent_IN_FWD" <<endl; 
466
 
467
 
468
                if(lk_consume_fc.read()){
469
#ifdef RETRY_MODE_ENABLED
470
                        //If in retry mode, the nop CRC must be sent
471
                        if(csr_retry.read()){
472
                                go_NOP_CRC_SENT_IN_FWD();
473
                        }
474
                        else
475
#endif
476
                        {
477
                                //If a nop is requested again, send another
478
                                if (nop_req == true)
479
                                        go_NOP_SENT_IN_FWD();
480
                                //Otherwise continue to send data
481
                                else
482
                                        go_FWD_DATA_SENT();
483
                        }
484
                }
485
                //If output not consumed, don't modify the output
486
                else{
487
                        next_state = NOP_SENT_IN_FWD;
488
                        next_fc_lctl_lk = true;
489
                        next_fc_hctl_lk = true;
490
                }
491
 
492
                break;
493
 
494
 
495
        case USER_CMD32_SENT:
496
                {
497
#ifdef RETRY_MODE_ENABLED
498
                        add_to_history = lk_consume_fc.read();
499
#endif
500
 
501
                        //If output not consumed, don't modify the output
502
                        if(!lk_consume_fc.read()){
503
                                next_state = USER_CMD32_SENT;
504
                                next_fc_lctl_lk = true;
505
                                next_fc_hctl_lk = true;
506
                        }
507
                        //If there is data with this packet
508
                        else if (has_data.read()){
509
                                //If a request for nop, interrupt sending the data to send nop
510
                                if (nop_req == true){
511
                                        go_NOP_SENT_IN_USER();
512
                                }
513
                                //Otherwise go send the data
514
                                else{
515
                                        go_USER_DATA_SENT();
516
                                }
517
                        }
518
#ifdef RETRY_MODE_ENABLED
519
                        else if(csr_retry.read()){
520
                                go_SEND_CMD_CRC();
521
                        }
522
#endif
523
                        //No data and no retry mode means packet sent : find next packet to send
524
                        else{
525
                                set_next_state();
526
                        }
527
                }
528
                break;
529
 
530
        case USER_CMD64_FIRST_SENT:
531
                {
532
#ifdef RETRY_MODE_ENABLED
533
                        add_to_history = lk_consume_fc.read();
534
#endif
535
 
536
                        //If output not consumed, don't modify the output
537
                        if(!lk_consume_fc.read()){
538
                                next_state = USER_CMD64_FIRST_SENT;
539
                                next_fc_lctl_lk = true;
540
                                next_fc_hctl_lk = true;
541
                        }
542
                        else{
543
                                next_state = USER_CMD64_SECOND_SENT;
544
                                fc_ctr_mux = FC_MUX_UI_MSB; //32 bits lsb FWD_CMD
545
                                next_fc_lctl_lk = true;
546
                                next_fc_hctl_lk = true;
547
                                consume_user_fifo = true;
548
#ifdef RETRY_MODE_ENABLED
549
                                next_calculate_crc = true;
550
                                add_to_history = true;
551
#endif
552
                        }
553
                }
554
                break;
555
 
556
        case USER_CMD64_SECOND_SENT:
557
 
558
#ifdef RETRY_MODE_ENABLED
559
                add_to_history = lk_consume_fc.read();
560
#endif
561
 
562
                //If output not consumed, don't modify the output
563
                if(!lk_consume_fc.read()){
564
                        next_state = USER_CMD64_SECOND_SENT;
565
                        next_fc_lctl_lk = true;
566
                        next_fc_hctl_lk = true;
567
                }
568
                //If there is data with this packet
569
                else if (has_data.read()){
570
                        //If a request for nop, interrupt sending the data to send nop
571
                        if (nop_req == true)
572
                                go_NOP_SENT_IN_USER();
573
                        //Otherwise go send the data
574
                        else{
575
                                go_USER_DATA_SENT();
576
                        }
577
                }
578
#ifdef RETRY_MODE_ENABLED
579
                else if(csr_retry.read()){
580
                        go_SEND_CMD_CRC();
581
                }
582
#endif
583
                //No data and no retry mode means packet sent : find next packet to send
584
                else {
585
                        set_next_state();
586
                }
587
                break;
588
 
589
        case USER_DATA_SENT:
590
 
591
#ifdef RETRY_MODE_ENABLED
592
                add_to_history = lk_consume_fc.read();
593
#endif
594
 
595
                //If output not consumed, don't modify the output
596
                if(!lk_consume_fc.read()){
597
                        next_state = USER_DATA_SENT;
598
                        next_fc_lctl_lk = false;
599
                        next_fc_hctl_lk = false;
600
                }
601
                //If there is data left to send
602
                else if (has_data.read()){
603
                        //If a request for nop, interrupt sending the data to send nop
604
                        if (nop_req == true)
605
                                go_NOP_SENT_IN_USER();
606
                        //Otherwise keep sending data
607
                        else
608
                                go_USER_DATA_SENT();
609
                }
610
#ifdef RETRY_MODE_ENABLED
611
                else if(csr_retry.read()){
612
                        go_SEND_DATA_CRC();
613
                }
614
#endif
615
                //No data and no retry mode means packet sent : find next packet to send
616
                else {
617
                        set_next_state();
618
                }
619
 
620
                break;
621
 
622
        case NOP_SENT_IN_USER:
623
 
624
                if(lk_consume_fc.read()){
625
#ifdef RETRY_MODE_ENABLED
626
                        //If in retry mode, nop CRC must be sent
627
                        if(csr_retry.read()){
628
                                fc_nop_sent = false;
629
                                next_state = NOP_CRC_SENT_IN_USER;
630
                                next_fc_lctl_lk = true;
631
                                next_fc_hctl_lk = false;
632
                                next_select_nop_crc_output = true;
633
                        }
634
                        else
635
#endif
636
                        {
637
                                //If nop is requestion, send another nop
638
                                if (nop_req == true)
639
                                        go_NOP_SENT_IN_USER();
640
                                //Otherwise, keep sending data
641
                                else
642
                                        go_USER_DATA_SENT();
643
                        }
644
                }
645
                //If output not consumed, don't modify the output
646
                else{
647
                        next_state = NOP_SENT_IN_USER;
648
                        next_fc_lctl_lk = true;
649
                        next_fc_hctl_lk = true;
650
                }
651
 
652
                break;
653
 
654
 
655
        case EH_CMD_SENT:
656
                {
657
#ifdef RETRY_MODE_ENABLED
658
                        add_to_history = lk_consume_fc.read();
659
#endif
660
 
661
                        //If output not consumed, don't modify the output
662
                        if(!lk_consume_fc.read()){
663
                                next_state = EH_CMD_SENT;
664
                                next_fc_lctl_lk = true;
665
                                next_fc_hctl_lk = true;
666
                        }
667
                        //If there is data with this packet
668
                        else if (has_data.read()){
669
                                //If a request for nop, interrupt sending the data to send nop
670
                                if (nop_req == true){
671
                                        go_NOP_SENT_IN_EH();
672
                                }
673
                                //Otherwise go send the data
674
                                else{
675
                                        go_ERROR_DATA_SENT();
676
                                }
677
                        }
678
#ifdef RETRY_MODE_ENABLED
679
                        else if(csr_retry.read()){
680
                                go_SEND_CMD_CRC();
681
                        }
682
#endif
683
                        //No data and no retry mode means packet sent : find next packet to send
684
                        else{
685
                                set_next_state();
686
                        }
687
                }
688
                break;
689
 
690
        case CSR_CMD_SENT:
691
                {
692
 
693
                //cout << "entering CSR_CMD_SENT" <<endl;
694
#ifdef RETRY_MODE_ENABLED
695
                        add_to_history = lk_consume_fc.read();
696
#endif
697
 
698
                        //If output not consumed, don't modify the output
699
                        if(!lk_consume_fc.read()){
700
                                next_state = CSR_CMD_SENT;
701
                                next_fc_lctl_lk = true;
702
                                next_fc_hctl_lk = true;
703
                        }
704
                        //If there is data with this packet
705
                        else if (has_data.read()){
706
                                //If a request for nop, interrupt sending the data to send nop
707
                                if (nop_req == true){
708
                                        go_NOP_SENT_IN_CSR();
709
                                }
710
                                //Otherwise go send the data
711
                                else{
712
                                        go_CSR_DATA_SENT();
713
                                }
714
                        }
715
#ifdef RETRY_MODE_ENABLED
716
                        else if(csr_retry.read()){
717
                                go_SEND_CMD_CRC();
718
                        }
719
#endif
720
                        //No data and no retry mode means packet sent : find next packet to send
721
                        else{
722
                                set_next_state();
723
                        }
724
                }
725
                break;
726
 
727
 
728
 
729
        case ERROR_DATA_SENT:
730
 
731
#ifdef RETRY_MODE_ENABLED
732
                add_to_history = lk_consume_fc.read();
733
#endif
734
 
735
                //If output not consumed, don't modify the output
736
                if(!lk_consume_fc.read()){
737
                        next_state = ERROR_DATA_SENT;
738
                        next_fc_lctl_lk = false;
739
                        next_fc_hctl_lk = false;
740
                }
741
                //If there is data left to send
742
                else if (has_data.read()){
743
                        //If a request for nop, interrupt sending the data to send nop
744
                        if (nop_req == true)
745
                                go_NOP_SENT_IN_EH();
746
                        //Otherwise keep sending data
747
                        else
748
                                go_ERROR_DATA_SENT();
749
                }
750
#ifdef RETRY_MODE_ENABLED
751
                else if(csr_retry.read()){
752
                        go_SEND_DATA_CRC();
753
                }
754
#endif
755
                //No data and no retry mode means packet sent : find next packet to send
756
                else {
757
                        set_next_state();
758
                }
759
 
760
                break;
761
 
762
        case NOP_SENT_IN_EH:
763
 
764
                if(lk_consume_fc.read()){
765
#ifdef RETRY_MODE_ENABLED
766
                        //If in retry mode, nop CRC must be sent
767
                        if(csr_retry.read()){
768
                                next_select_nop_crc_output = true;
769
                                fc_nop_sent = false;
770
                                next_state = NOP_CRC_SENT_IN_EH;
771
                                next_fc_lctl_lk = true;
772
                                next_fc_hctl_lk = false;
773
                        }
774
                        else
775
#endif
776
                        {
777
                                //If nop is requestion, send another nop
778
                                if (nop_req == true)
779
                                        go_NOP_SENT_IN_EH();
780
                                //Otherwise, keep sending data
781
                                else
782
                                        go_ERROR_DATA_SENT();
783
                        }
784
                }
785
                //If output not consumed, don't modify the output
786
                else{
787
                        next_state = NOP_SENT_IN_EH;
788
                        next_fc_lctl_lk = true;
789
                        next_fc_hctl_lk = true;
790
                }
791
                break;
792
 
793
        case CSR_DATA_SENT:
794
 
795
#ifdef RETRY_MODE_ENABLED
796
                add_to_history = lk_consume_fc.read();
797
#endif
798
                //If output not consumed, don't modify the output
799
                if(!lk_consume_fc.read()){
800
                        next_state = CSR_DATA_SENT;
801
                        next_fc_lctl_lk = false;
802
                        next_fc_hctl_lk = false;
803
                }
804
                //If there is data left to send
805
                else if (has_data.read()){
806
                        //If a request for nop, interrupt sending the data to send nop
807
                        if (nop_req == true)
808
                                go_NOP_SENT_IN_CSR();
809
                        //Otherwise keep sending data
810
                        else
811
                                go_CSR_DATA_SENT();
812
                }
813
#ifdef RETRY_MODE_ENABLED
814
                else if(csr_retry.read()){
815
                        go_SEND_DATA_CRC();
816
                }
817
#endif
818
                //No data and no retry mode means packet sent : find next packet to send
819
                else {
820
                        set_next_state();
821
                }
822
 
823
                break;
824
 
825
        case NOP_SENT_IN_CSR:
826
 
827
                if(lk_consume_fc.read()){
828
#ifdef RETRY_MODE_ENABLED
829
                        //If in retry mode, nop CRC must be sent
830
                        if(csr_retry.read()){
831
                                next_select_nop_crc_output = true;
832
                                fc_nop_sent = false;
833
                                next_state = NOP_CRC_SENT_IN_CSR;
834
                                next_fc_lctl_lk = true;
835
                                next_fc_hctl_lk = false;
836
                        }
837
                        else
838
#endif
839
                        {
840
                                //If nop is requestion, send another nop
841
                                if (nop_req == true)
842
                                        go_NOP_SENT_IN_CSR();
843
                                //Otherwise, keep sending data
844
                                else
845
                                        go_CSR_DATA_SENT();
846
                        }
847
                }
848
                //If output not consumed, don't modify the output
849
                else{
850
                        next_state = NOP_SENT_IN_CSR;
851
                        next_fc_lctl_lk = true;
852
                        next_fc_hctl_lk = true;
853
                }
854
                break;
855
 
856
        //This outputs nop disconnects.  When ldtstopx is done, then we go back
857
        //to normal operation.  The link will disconnect on it's own
858
        case LDTSTOP_DISCONNECT:
859
                //Disconnect is not activated because the link will start
860
                //it's deconnect sequence when it reads ldtstopx.  It will
861
                //take a long delay (minimum 64 dword) before it's deconnected
862
                //because of the periodic CRC that must be sent
863
                //
864
                //fc_disconnect_lk is reserved for RETRY disconnect
865
                //next_fc_disconnect_lk = true;
866
 
867
#ifdef RETRY_MODE_ENABLED
868
                //Clear CRC so it's clean when we start over
869
                clear_crc = true;
870
                clear_nop_crc = true;
871
#endif
872
                //While ldtstopx is maintained, stay in ldstopx state
873
                if(ldtstopx.read() == false){
874
                        go_LDTSTOP_DISCONNECT();
875
                }
876
                //Once done, go back to normal operation by starting with a nop
877
                else{
878
                        go_NOP_SENT();
879
                }
880
                break;
881
 
882
////////////////////////////////////////////
883
//                              MAIN CRC states
884
///////////////////////////////////////////
885
 
886
#ifdef RETRY_MODE_ENABLED
887
 
888
        case NOP_CRC_SENT_IN_CSR:
889
 
890
                clear_nop_crc = lk_consume_fc.read();
891
 
892
                if(lk_consume_fc.read()){
893
                        go_CSR_DATA_SENT();
894
                }
895
                else{
896
                        next_state = NOP_CRC_SENT_IN_CSR;
897
                        next_fc_lctl_lk = true;
898
                        next_fc_hctl_lk = false;
899
                        next_select_nop_crc_output = true;
900
                }
901
                break;
902
 
903
        case NOP_CRC_SENT_IN_FWD:
904
 
905
                clear_nop_crc = lk_consume_fc.read();
906
 
907
                if(lk_consume_fc.read()){
908
                        go_FWD_DATA_SENT();
909
                }
910
                else{
911
                        next_state = NOP_CRC_SENT_IN_FWD;
912
                        next_fc_lctl_lk = true;
913
                        next_fc_hctl_lk = false;
914
                        next_select_nop_crc_output = true;
915
                }
916
 
917
                break;
918
 
919
        case NOP_CRC_SENT_IN_USER:
920
 
921
                clear_nop_crc = lk_consume_fc.read();
922
 
923
                if(lk_consume_fc.read()){
924
                        go_USER_DATA_SENT();
925
                }
926
                else{
927
                        next_state = NOP_CRC_SENT_IN_USER;
928
                        next_fc_lctl_lk = true;
929
                        next_fc_hctl_lk = false;
930
                        next_select_nop_crc_output = true;
931
                }
932
                break;
933
 
934
        case NOP_CRC_SENT_IN_EH:
935
 
936
                clear_nop_crc = lk_consume_fc.read();
937
 
938
                if(lk_consume_fc.read()){
939
                        go_ERROR_DATA_SENT();
940
                }
941
                else{
942
                        next_state = NOP_CRC_SENT_IN_EH;
943
                        next_fc_lctl_lk = true;
944
                        next_fc_hctl_lk = false;
945
                        next_select_nop_crc_output = true;
946
                }
947
                break;
948
 
949
        case SEND_DATA_CRC:
950
 
951
                //cout << "entering SEND_DATA_CRC" <<endl;      
952
 
953
                if(!lk_consume_fc.read()){
954
                        next_fc_lctl_lk = false;
955
                        next_fc_hctl_lk = true;
956
                        next_state = SEND_DATA_CRC;
957
                        next_select_crc_output = true;
958
                }
959
                else{
960
                        clear_crc = true;
961
                        set_next_state();
962
                }
963
                break;
964
 
965
        case SEND_CMD_CRC:
966
 
967
                if(!lk_consume_fc.read()){
968
                        next_fc_lctl_lk = true;
969
                        next_fc_hctl_lk =  false;
970
                        next_state = SEND_CMD_CRC;
971
                        next_select_crc_output = true;
972
                }
973
                else{
974
                        clear_crc = true;
975
                        set_next_state();
976
                }
977
                break;
978
 
979
        case SEND_NOP_CRC:
980
 
981
                if(!lk_consume_fc.read()){
982
                        next_fc_lctl_lk = true;
983
                        next_fc_hctl_lk =  false;
984
                        next_state = SEND_NOP_CRC;
985
                        next_select_nop_crc_output = true;
986
                }
987
                else{
988
                        clear_nop_crc = true;
989
                        set_next_state();
990
                }
991
                break;
992
 
993
        case RETRY_SEND_DISCONNECT:
994
 
995
                //If was playing back history, stop it.  If not, this simply does nothing
996
                stop_history_playback = true;
997
 
998
                if(!lk_consume_fc.read()){
999
                        next_fc_lctl_lk = true;
1000
                        next_fc_hctl_lk =  true;
1001
                        next_state = RETRY_SEND_DISCONNECT;
1002
                        next_fc_disconnect_lk = false;
1003
                }
1004
                else{
1005
                        next_fc_lctl_lk = true;
1006
                        next_fc_hctl_lk =  false;
1007
                        next_state = RETRY_SEND_DISCONNECT_CRC;
1008
                        next_select_nop_crc_output = true;
1009
                        //When the link detects fc_disconnect_lk, it finishes sending the dword currently
1010
                        //on it's output and then starts sending warm reset signaling.  fc_disconnect_lk
1011
                        //is activated on the next cycle, when the CRC is outputed to the links.  The CRC
1012
                        //will be the last dword sent
1013
                        next_fc_disconnect_lk = true;
1014
                }
1015
                break;
1016
 
1017
        case RETRY_SEND_DISCONNECT_CRC:
1018
 
1019
                if(!lk_consume_fc.read()){
1020
                        next_state = RETRY_SEND_DISCONNECT_CRC;
1021
                        next_select_nop_crc_output = true;
1022
                }
1023
                else{
1024
                        next_state = RETRY_WAIT_FOR_RX_DISCONNECT;
1025
                        clear_nop_crc = true;
1026
                }
1027
                next_fc_lctl_lk = true;
1028
                next_fc_hctl_lk = false;
1029
 
1030
                next_fc_disconnect_lk = true;
1031
 
1032
        break;
1033
 
1034
        //The TX side of the link is disconnected, but if we initiated the retry
1035
        //attempt, the RX side might still be receiving stuff.  We wait for the RX
1036
        //side to be disconnected
1037
        case RETRY_WAIT_FOR_RX_DISCONNECT:
1038
 
1039
                //cout << "Entered RETRY_WAIT_FOR_RX_DISCONNECT" << endl;
1040
 
1041
                next_fc_lctl_lk = true;
1042
                next_fc_hctl_lk = true;
1043
                clear_crc = true;
1044
                clear_nop_crc = true;
1045
                clear_farend_count = true;
1046
                clear_retry_disconnect_initiated = true;
1047
 
1048
                if(registered_lk_rx_connected.read()){
1049
                        next_state = RETRY_WAIT_FOR_RX_DISCONNECT;
1050
                        next_fc_disconnect_lk = true;
1051
                }
1052
                else{
1053
                        next_state = RETRY_WAIT_FOR_ACK_AND_BUFFER_COUNT_SENT;
1054
                        next_fc_lctl_lk = true;
1055
                        next_fc_hctl_lk = true;
1056
                        fc_ctr_mux = FC_MUX_NOP;
1057
                        fc_nop_sent = true;
1058
                        next_calculate_nop_crc = true;
1059
                        next_fc_disconnect_lk = false;
1060
                }
1061
                break;
1062
 
1063
        //To know where to start the resend, we wait for a nop with the last
1064
        //acked packet value.  We also have to finish transmitting all our
1065
        //buffer counts
1066
        case RETRY_WAIT_FOR_ACK_AND_BUFFER_COUNT_SENT:
1067
                begin_history_playback = received_ack.read();
1068
 
1069
                if(!lk_consume_fc.read()){
1070
                        next_fc_lctl_lk = true;
1071
                        next_fc_hctl_lk =  true;
1072
                        next_state = RETRY_WAIT_FOR_ACK_AND_BUFFER_COUNT_SENT;
1073
                }
1074
                else{
1075
                        next_state = RETRY_WAIT_FOR_ACK_AND_BUFFER_COUNT_SENT_CRC;
1076
                        next_fc_lctl_lk = true;
1077
                        next_fc_hctl_lk =  false;
1078
                        next_select_nop_crc_output = true;
1079
                }
1080
 
1081
                break;
1082
 
1083
        case RETRY_WAIT_FOR_ACK_AND_BUFFER_COUNT_SENT_CRC:
1084
                begin_history_playback = received_ack.read();
1085
 
1086
                if(!lk_consume_fc.read()){
1087
                        next_fc_lctl_lk = true;
1088
                        next_fc_hctl_lk =  false;
1089
                        next_state = RETRY_WAIT_FOR_ACK_AND_BUFFER_COUNT_SENT_CRC;
1090
                        next_select_nop_crc_output = true;
1091
                        next_state = RETRY_WAIT_FOR_ACK_AND_BUFFER_COUNT_SENT_CRC;
1092
 
1093
                }
1094
                else{
1095
                        fc_ctr_mux = FC_MUX_NOP;
1096
                        next_fc_lctl_lk = true;
1097
                        next_fc_hctl_lk = true;
1098
                        fc_nop_sent = true;
1099
                        clear_nop_crc = true;
1100
                        next_calculate_nop_crc = true;
1101
 
1102
                        /*Got ack and finished sending buffer count*/
1103
                        if(ldtstopx.read() == false || retry_disconnect_initiated.read()){
1104
                                go_RETRY_SEND_DISCONNECT();
1105
                        }
1106
                        //If this case happens, it means there is no history to play back
1107
                        if(history_playback_done.read() && history_playback_ready.read())
1108
                                next_state = NOP_SENT;
1109
                        //All buffers have been confirmed with nops and playback is ready, start playback
1110
                        else if(!has_nop_buffers_to_send.read()&& history_playback_ready.read())
1111
                                next_state = RETRY_NOP_SENT;
1112
                        else
1113
                                next_state = RETRY_WAIT_FOR_ACK_AND_BUFFER_COUNT_SENT;
1114
                }
1115
                break;
1116
 
1117
 
1118
        case RETRY_CMD32_SENT:
1119
                {
1120
                //cout << "entering USER_CMD_SENT" <<endl;
1121
 
1122
                        if(!lk_consume_fc.read()){
1123
                                next_state = FWD_CMD32_SENT;
1124
                                next_fc_lctl_lk = true;
1125
                                next_fc_hctl_lk = true;
1126
                        }
1127
                        else if (has_data.read()){
1128
                                if (nop_req == true){
1129
                                        go_RETRY_NOP_SENT_IN_DATA();
1130
                                }
1131
                                else{
1132
                                        go_RETRY_DATA_SENT();
1133
                                }
1134
                        }
1135
                        else{
1136
                                go_RETRY_SEND_CMD_CRC();
1137
                        }
1138
                }
1139
                break;
1140
 
1141
        case RETRY_CMD64_FIRST_SENT:
1142
                if(!lk_consume_fc.read()){
1143
                        next_state = RETRY_CMD64_FIRST_SENT;
1144
                        next_fc_lctl_lk = true;
1145
                        next_fc_hctl_lk = true;
1146
                }
1147
                else{
1148
                        next_state = RETRY_CMD64_SECOND_SENT;
1149
                        next_fc_lctl_lk = true;
1150
                        next_fc_hctl_lk = true;
1151
                        fc_ctr_mux = FC_MUX_HISTORY; //32 bits lsb FWD_CMD
1152
                        consume_history = true;
1153
                        next_calculate_crc = true;
1154
                }
1155
                break;
1156
        case RETRY_CMD64_SECOND_SENT:
1157
                if(!lk_consume_fc.read()){
1158
                        next_state = RETRY_CMD64_SECOND_SENT;
1159
                        next_fc_lctl_lk = true;
1160
                        next_fc_hctl_lk = true;
1161
                }
1162
                else if (has_data.read()){
1163
                        if (nop_req == true){
1164
                                go_RETRY_NOP_SENT_IN_DATA();
1165
                        }
1166
                        else{
1167
                                go_RETRY_DATA_SENT();
1168
                        }
1169
                }
1170
                else{
1171
                        go_RETRY_SEND_CMD_CRC();
1172
                }
1173
                break;
1174
 
1175
        case RETRY_DATA_SENT:
1176
                if(!lk_consume_fc.read()){
1177
                        next_state = RETRY_DATA_SENT;
1178
                        next_fc_lctl_lk = false;
1179
                        next_fc_hctl_lk = false;
1180
                }
1181
                else if (has_data.read()){
1182
                        if (nop_req == true){
1183
                                go_RETRY_NOP_SENT_IN_DATA();
1184
                        }
1185
                        else{
1186
                                go_RETRY_DATA_SENT();
1187
                        }
1188
                }
1189
                else{
1190
                        go_RETRY_SEND_CMD_CRC_DATA();
1191
                }
1192
                break;
1193
 
1194
        case RETRY_SEND_CMD_CRC:
1195
                clear_crc = lk_consume_fc.read();
1196
 
1197
                if(!lk_consume_fc.read()){
1198
                        next_state = RETRY_SEND_CMD_CRC;
1199
                        next_fc_lctl_lk = fc_lctl_lk.read();
1200
                        next_fc_hctl_lk = fc_hctl_lk.read();
1201
                        next_select_crc_output = true;
1202
                }
1203
                else{
1204
                        go_next_retry_state();
1205
                }
1206
                break;
1207
 
1208
        case RETRY_NOP_SENT_IN_DATA:
1209
 
1210
                if(lk_consume_fc.read()){
1211
                        next_state = RETRY_NOP_CRC_SENT_IN_DATA;
1212
                        next_fc_lctl_lk = true;
1213
                        next_fc_hctl_lk = false;
1214
                        next_select_nop_crc_output = true;
1215
                }
1216
                else{
1217
                        next_state = RETRY_NOP_SENT_IN_DATA;
1218
                        next_fc_lctl_lk = true;
1219
                        next_fc_hctl_lk = true;
1220
                }
1221
                break;
1222
 
1223
        case RETRY_NOP_CRC_SENT_IN_DATA:
1224
                clear_nop_crc = lk_consume_fc.read();
1225
 
1226
                if(lk_consume_fc.read()){
1227
                        if (nop_req == true)
1228
                                go_RETRY_NOP_SENT_IN_DATA();
1229
                        else
1230
                                go_RETRY_DATA_SENT();
1231
                }
1232
                else{
1233
                        next_state = RETRY_NOP_CRC_SENT_IN_DATA;
1234
                        next_fc_lctl_lk = true;
1235
                        next_fc_hctl_lk = false;
1236
                        next_select_nop_crc_output = true;
1237
                }
1238
                break;
1239
 
1240
        case RETRY_NOP_SENT:
1241
                //cout << "Entered RETRY_NOP_SENT state" << endl;
1242
                if(lk_consume_fc.read()){
1243
                        next_state = RETRY_NOP_CRC_SENT;
1244
                        next_fc_lctl_lk = true;
1245
                        next_fc_hctl_lk = false;
1246
                        next_select_nop_crc_output = true;
1247
                }
1248
                else{
1249
                        next_state = RETRY_NOP_SENT;
1250
                        next_fc_lctl_lk = true;
1251
                        next_fc_hctl_lk = true;
1252
                }
1253
                break;
1254
        case RETRY_NOP_CRC_SENT:
1255
                clear_nop_crc = lk_consume_fc.read();
1256
 
1257
                if(lk_consume_fc.read()){
1258
                        go_next_retry_state();
1259
                }
1260
                else{
1261
                        next_state = RETRY_NOP_CRC_SENT;
1262
                        next_fc_lctl_lk = true;
1263
                        next_fc_hctl_lk = false;
1264
                        next_select_nop_crc_output = true;
1265
                }
1266
 
1267
                break;
1268
////////////////////////////////////////////
1269
//                      End of MAIN CRC states
1270
///////////////////////////////////////////
1271
#endif
1272
 
1273
        //case TRANSMITTER_OFF_STATE:
1274
        default:
1275
        //case NOP_SENT:
1276
                //cout << "entering fc_nop_sent" <<endl;        
1277
                if(lk_consume_fc.read()){
1278
#ifdef RETRY_MODE_ENABLED
1279
                        if(csr_retry.read()){
1280
                                next_state = SEND_NOP_CRC;
1281
                                next_select_nop_crc_output = true;
1282
                                next_fc_lctl_lk = true;
1283
                                next_fc_hctl_lk = false;
1284
                        }
1285
                        else
1286
#endif
1287
                                set_next_state();
1288
                }
1289
                else{
1290
                        next_state = NOP_SENT;
1291
                        next_fc_lctl_lk = true;
1292
                        next_fc_hctl_lk = true;
1293
                }
1294
        } // end of switch
1295
} // end of fonction
1296
 
1297
 
1298
void flow_control_l3::set_next_state() {
1299
 
1300
        /**
1301
                Basically, this only outputs what's been calculated in
1302
                find_next_state.  The reason for not calling directly call_next_state
1303
                is that there are a lot of calls for this in the MSA and ususually,
1304
                SystemC synthesis tools unroll functions, so the resulting .vhdl output
1305
                is VERY big!  This way, only this small part get unrolled multiple times,
1306
                resulting in a much smaller and faster to compile file.  find_next_state
1307
                is treated a single parallel process.  We're talking 2K lines versus 15K.
1308
        */
1309
 
1310
        next_state = found_next_state;
1311
 
1312
#ifdef RETRY_MODE_ENABLED
1313
        new_history_entry_size_m1 = found_new_history_entry_size_m1;
1314
        new_history_entry = found_new_history_entry;
1315
        clear_crc = true;
1316
        clear_nop_crc = true;
1317
        next_calculate_crc = found_next_calculate_crc;
1318
        next_calculate_nop_crc = found_next_calculate_nop_crc;
1319
#endif
1320
 
1321
        fwd_ack_ro = found_load_fwd_pkt;
1322
        fc_ack_eh = found_load_eh_pkt;
1323
        fc_ack_csr = found_load_csr_pkt;
1324
        consume_user_fifo = found_load_user_fifo_pkt;
1325
        hold_user_fifo = found_hold_user_fifo_pkt;
1326
        generate_disconnect_nop = found_generate_disconnect_nop;
1327
        fc_nop_sent = found_fc_nop_sent;
1328
        fwd_vctype_db = found_fwd_vctype_db;
1329
        fwd_address_db = found_fwd_address_db;
1330
        next_data_cnt = found_next_data_cnt;
1331
        next_has_data = found_next_has_data;
1332
        fc_data_vc_ui = found_fc_data_vc_ui;
1333
        current_sent_type = found_current_sent_type;
1334
 
1335
        local_packet_issued = found_local_packet_issued;
1336
        for(int n = 0; n < 3; n++)
1337
                next_fairness_vc_reserved[n] = found_next_fairness_vc_reserved[n];
1338
 
1339
        next_chain_current_state = found_next_chain_current_state;
1340
 
1341
        fc_ctr_mux = found_fc_ctr_mux;
1342
        next_fc_lctl_lk = true;
1343
        next_fc_hctl_lk = true;
1344
}
1345
 
1346
 
1347
void flow_control_l3::find_next_state() {
1348
        //Reserving a packet to fairness to make sure not to starve a VC
1349
        bool reserve_fairness = false;
1350
        //If forward has priority but a packet was previously reserved
1351
        bool fairness_override = false;
1352
 
1353
        //By default don't change the fairness reserved bit
1354
        for(int n = 0; n < 3; n++)
1355
                found_next_fairness_vc_reserved[n] = fairness_vc_reserved[n];
1356
 
1357
        //Find if we're requesting a nop
1358
        bool nop_req = ro_nop_req_fc.read() || db_nop_req_fc.read() || nop_next_to_send.read();
1359
 
1360
        bool disconnect = (ldtstopx.read() == false
1361
#ifdef RETRY_MODE_ENABLED
1362
                        || cd_initiate_retry_disconnect.read() ||
1363
                        registered_lk_initiate_retry_disconnect.read() ||
1364
                        retry_disconnect_initiated.read()
1365
#endif
1366
                        );
1367
        bool send_nop = nop_req || disconnect;
1368
 
1369
        /**
1370
                First, we look if a packet can be sent - needs to be one available and the necessary
1371
                buffers in the other link must be free
1372
    */
1373
        sc_bv<6> csr_cmd_bits;
1374
        csr_cmd_bits = csr_dword_fc.read().range(5,0);
1375
 
1376
        //***********************************************
1377
        //Analyse if the packet from the CSR can be sent
1378
        //***********************************************
1379
        //Some packet analysis
1380
        PacketCommand csr_cmd = getPacketCommand(csr_cmd_bits);
1381
        VirtualChannel csr_vc = VC_RESPONSE;
1382
        bool csr_data_associated = hasDataAssociated(csr_cmd);
1383
        sc_uint<5> csr_size_with_data_m1 =
1384
                getDwordPacketSizeWithDatam1(sc_bv<64>(csr_dword_fc.read()),csr_cmd);
1385
        sc_uint<4> csr_data_count = getDataLengthm1(sc_bv<64>(csr_dword_fc.read()));
1386
        //We know csr can only send responses, check if the next buffer has room for
1387
        //a response packet, and data if there is data associated with that response
1388
        //Also check it there IS a packet!  and if in retry mode, if we have enough room
1389
        //in history
1390
        bool csr_can_be_sent = (csr_available_fc == true) &&
1391
                        (fwd_next_node_buffer_status_ro.read()[BUF_STATUS_R_CMD] == true) &&
1392
                        (fwd_next_node_buffer_status_ro.read()[BUF_STATUS_R_DATA] == true || !csr_data_associated)
1393
#ifdef RETRY_MODE_ENABLED
1394
                        && (room_available_in_history.read() || !csr_retry.read())
1395
#endif
1396
                        ;
1397
 
1398
        if(!local_priority.read() && fairness_vc_reserved[csr_vc].read() && csr_can_be_sent)
1399
                fairness_override = true;
1400
        if(csr_available_fc == true && !csr_can_be_sent &&
1401
                local_priority.read() && fairness_vc_reserved[csr_vc].read())
1402
                reserve_fairness = true;
1403
 
1404
        //*********************************************************
1405
        //Analyse if the packet from the Error handler can be sent
1406
        //*********************************************************
1407
        sc_bv<6> eh_cmd_bits;
1408
        eh_cmd_bits = eh_cmd_data_fc.read().range(5,0);
1409
 
1410
        PacketCommand eh_cmd = getPacketCommand(eh_cmd_bits);
1411
        VirtualChannel eh_vc = VC_RESPONSE;
1412
        bool eh_data_associated = hasDataAssociated(eh_cmd);
1413
        sc_uint<5> eh_size_with_data_m1 = getDwordPacketSizeWithDatam1(sc_bv<64>(eh_cmd_data_fc.read()),eh_cmd);
1414
        sc_uint<4> eh_data_count = getDataLengthm1(sc_bv<64>(eh_cmd_data_fc.read()));
1415
        //We know csr can only send responses, check if the next buffer has room for
1416
        //a response packet, and data if there is data associated with that response
1417
        //Also check it there IS a packet!  and if in retry mode, if we have enough room
1418
        //in history
1419
        bool eh_can_be_sent = (eh_available_fc == true) &&
1420
                        (fwd_next_node_buffer_status_ro.read()[BUF_STATUS_R_CMD] == true) &&
1421
                        (fwd_next_node_buffer_status_ro.read()[BUF_STATUS_R_DATA] == true || !eh_data_associated)
1422
#ifdef RETRY_MODE_ENABLED
1423
                         && (room_available_in_history.read() || !csr_retry.read())
1424
#endif
1425
                        ;
1426
 
1427
        if(!local_priority.read() && fairness_vc_reserved[eh_vc].read() && eh_can_be_sent)
1428
                fairness_override = true;
1429
        if(eh_available_fc == true && !eh_can_be_sent &&
1430
                local_priority.read() && fairness_vc_reserved[eh_vc].read())
1431
                reserve_fairness = true;
1432
 
1433
 
1434
        //*************************************************************
1435
        //Analyse if the packet from the internal user fifo can be sent
1436
        //*************************************************************
1437
        bool user_can_be_sent = fifo_user_available.read() &&
1438
                verify_buffer_status(fifo_user_packet_vc.read(),fifo_user_packet_data_asociated.read())
1439
#ifdef RETRY_MODE_ENABLED
1440
                 && (room_available_in_history.read() || !csr_retry.read())
1441
#endif
1442
        ;
1443
 
1444
#ifdef RETRY_MODE_ENABLED
1445
        sc_uint<5> fifo_user_packet_with_data_m1 =
1446
                getPacketSizeWithDatam1(fifo_user_packet.read(),fifo_user_packet_command.read());
1447
#endif
1448
 
1449
        if(!local_priority.read() && fairness_vc_reserved[fifo_user_packet_vc.read()].read() && user_can_be_sent)
1450
                fairness_override = true;
1451
 
1452
        /** This way to reserve fairness might stop a eh or csr packet from being sent immediately, but it
1453
                will simply be sent a bit later that's all.  And since the eh and csr traffic is rare, it does
1454
                not cause problem.
1455
        */
1456
        if(fifo_user_available == true && !user_can_be_sent
1457
                && local_priority.read() && !fairness_vc_reserved[fifo_user_packet_vc.read()].read())
1458
                reserve_fairness = true;
1459
 
1460
        /**
1461
                For the fairness algorithm, a packet from csr, user or eh is considered a
1462
                local packet.  We check if a local packet can be sent
1463
        */
1464
        bool local_req = csr_can_be_sent || eh_can_be_sent || user_can_be_sent;
1465
 
1466
        /**
1467
                If a fairness slot is reserved, it is for a specific VC, choose this VC
1468
        */
1469
        VirtualChannel reserve_vc;
1470
        if(eh_available_fc.read() || csr_available_fc.read())reserve_vc = VC_RESPONSE;
1471
        else reserve_vc = fifo_user_packet_vc.read();
1472
 
1473
 
1474
        /**
1475
                While we are at it, also check if the forward packet can be sent
1476
        */
1477
        sc_bv<6> fwd_cmd_bits;
1478
        sc_bv<64> ro_packet_fwd_buf = ro_packet_fwd.read().packet;
1479
        fwd_cmd_bits = ro_packet_fwd_buf.range(5,0);
1480
 
1481
        PacketCommand fwd_cmd = getPacketCommand(fwd_cmd_bits);
1482
        bool fwd_data_associated = hasDataAssociated(fwd_cmd);
1483
        sc_uint<5> fwd_size_with_data_m1 = getPacketSizeWithDatam1(ro_packet_fwd.read().packet,fwd_cmd);
1484
        sc_uint<4> fwd_data_count = getDataLengthm1(sc_bv<64>(ro_packet_fwd.read().packet));
1485
 
1486
 
1487
        /*Also, the error handler shares the line with the fwd, so if the
1488
                error64BitExtension is on, the packet is not for us...*/
1489
        bool fwd_can_be_sent = ro_available_fwd.read() &&
1490
                verify_buffer_status(ro_packet_vc_fwd.read(),fwd_data_associated)  &&
1491
                !ro_packet_fwd.read().error64BitExtension &&
1492
                //If we are currently sending a user chain and the fwd packet is POSTED, we can't send
1493
                !(chain_current_state == USER_CHAIN_STATE && ro_packet_vc_fwd.read() == VC_POSTED) &&
1494
                //Dont send a packet in a VC reserved for local
1495
                !fairness_vc_reserved[ro_packet_vc_fwd.read()].read()
1496
#ifdef RETRY_MODE_ENABLED
1497
                && (room_available_in_history.read() || !csr_retry.read())
1498
#endif
1499
                ;
1500
        bool fwd_chain = isChain(ro_packet_fwd.read().packet);
1501
 
1502
        /** Nop request always has the absolute priority
1503
        */
1504
 
1505
        //default
1506
#ifdef RETRY_MODE_ENABLED
1507
        found_new_history_entry_size_m1 = 0;
1508
        found_new_history_entry = false;
1509
        found_next_calculate_crc = true;
1510
        found_next_calculate_nop_crc = false;
1511
#endif
1512
        found_load_fwd_pkt = false;
1513
        found_next_chain_current_state = chain_current_state;
1514
        found_load_csr_pkt = false;
1515
        found_load_user_fifo_pkt = false;
1516
        found_hold_user_fifo_pkt = false;
1517
        found_load_eh_pkt = false;
1518
        found_generate_disconnect_nop = false;
1519
        found_fc_nop_sent = false;
1520
        found_fwd_vctype_db =  buffered_fwd_vctype_db.read();
1521
        found_fwd_address_db =  buffered_fwd_address_db.read();
1522
        found_next_data_cnt = 0;
1523
        found_next_has_data = false;
1524
        //send early in which VC data might be read
1525
        found_fc_data_vc_ui = fifo_user_packet_vc.read();
1526
        found_fwd_vctype_db = VC_NONE;
1527
        found_local_packet_issued = false;
1528
        found_current_sent_type = 0;
1529
 
1530
 
1531
        //******************************
1532
        //Select the next state
1533
        //******************************
1534
 
1535
 
1536
        /*  If there is a forward packet to be sent and that either there is no
1537
        local packet to send or it the priority of the forward to send.*/
1538
        if (fwd_can_be_sent && !send_nop &&
1539
                //If local has a packet and has priority, we don't send
1540
                (local_priority.read() == false || local_req == false
1541
                || reserve_fairness) && !fairness_override )
1542
        {
1543
 
1544
                //Log the chain state
1545
                if(ro_packet_vc_fwd.read() == VC_POSTED){
1546
                        if(fwd_chain) found_next_chain_current_state = FWD_CHAIN_STATE;
1547
                        else found_next_chain_current_state = NO_CHAIN_STATE;
1548
                }
1549
 
1550
                //Choose the correct destination state depending 
1551
                //on if the packet is of dword length or not
1552
                if (isDwordPacket(ro_packet_fwd.read().packet,fwd_cmd))  {
1553
                        found_next_state = FWD_CMD32_SENT;
1554
                        found_load_fwd_pkt = true;
1555
                }
1556
                else{
1557
                        found_next_state = FWD_CMD64_FIRST_SENT;
1558
                }
1559
#ifdef RETRY_MODE_ENABLED
1560
                found_new_history_entry_size_m1 = fwd_size_with_data_m1;
1561
                found_new_history_entry = true;
1562
#endif
1563
                found_next_data_cnt = fwd_data_count;
1564
                found_next_has_data = fwd_data_associated;
1565
                found_fwd_vctype_db = ro_packet_vc_fwd.read();
1566
                found_fwd_address_db = ro_packet_fwd.read().data_address;
1567
                found_fc_ctr_mux = FC_MUX_FWD_LSB;
1568
                set_found_sent_type(ro_packet_vc_fwd.read(),fwd_data_associated);
1569
 
1570
                if(reserve_fairness){
1571
                        found_local_packet_issued = true;
1572
                        found_next_fairness_vc_reserved[reserve_vc] = true;
1573
                }
1574
        }
1575
        /*  Next in priority is the error handler.  It should not generate too much traffic*/
1576
        else if (eh_can_be_sent && !send_nop &&
1577
                        (local_priority.read() || fairness_vc_reserved[VC_RESPONSE].read() || !fwd_can_be_sent))
1578
        {
1579
                found_load_eh_pkt = true;
1580
                found_next_state = EH_CMD_SENT;
1581
 
1582
#ifdef RETRY_MODE_ENABLED
1583
                found_new_history_entry_size_m1 = eh_size_with_data_m1;
1584
                found_new_history_entry = true;
1585
#endif
1586
                found_next_data_cnt = eh_data_count;
1587
                found_next_has_data = eh_data_associated;
1588
                found_fc_ctr_mux = FC_MUX_EH;
1589
 
1590
                if(local_priority.read())
1591
                        found_local_packet_issued = true;
1592
                else
1593
                        found_next_fairness_vc_reserved[VC_RESPONSE] = false;
1594
 
1595
                //EH ALWAYS and ONLY produces responses
1596
                set_found_sent_type(VC_RESPONSE,eh_data_associated);
1597
        }
1598
        /*  Next in priority is the CSR.  It should not generate too much traffic
1599
                after init*/
1600
        else if(csr_can_be_sent && !send_nop &&
1601
                        (local_priority.read() || fairness_vc_reserved[VC_RESPONSE].read() || !fwd_can_be_sent))
1602
        {
1603
                found_load_csr_pkt = true;
1604
                found_next_state = CSR_CMD_SENT;
1605
 
1606
#ifdef RETRY_MODE_ENABLED
1607
                found_new_history_entry_size_m1 = csr_size_with_data_m1;
1608
                found_new_history_entry = true;
1609
#endif
1610
                found_next_data_cnt = csr_data_count;
1611
                found_next_has_data = csr_data_associated;
1612
                found_fc_ctr_mux = FC_MUX_CSR;
1613
 
1614
                if(local_priority.read())
1615
                        found_local_packet_issued = true;
1616
                else
1617
                        found_next_fairness_vc_reserved[VC_RESPONSE] = false;
1618
 
1619
                //CSR ALWAYS and ONLY produces responses
1620
                set_found_sent_type(VC_RESPONSE,csr_data_associated);
1621
        }
1622
        /*  Next in priority is the packets from the user*/
1623
        else if(user_can_be_sent && !send_nop &&
1624
                !(chain_current_state == FWD_CHAIN_STATE && fifo_user_packet_vc.read() == VC_POSTED) ){
1625
 
1626
                bool isChain = fifo_user_packet_isChain.read();
1627
                //Log the chain state
1628
                if(fifo_user_packet_vc.read() == VC_POSTED){
1629
                        if(isChain) found_next_chain_current_state = USER_CHAIN_STATE;
1630
                        else found_next_chain_current_state = NO_CHAIN_STATE;
1631
                }
1632
 
1633
                //Choose the correct destination state depending 
1634
                //on if the packet is of dword length or not
1635
                if (fifo_user_packet_dword.read())  {
1636
                        found_next_state = USER_CMD32_SENT;
1637
                        found_load_user_fifo_pkt = true;
1638
                }
1639
                else{
1640
                        found_next_state = USER_CMD64_FIRST_SENT;
1641
                        found_hold_user_fifo_pkt = true;
1642
                }
1643
                found_fc_ctr_mux = FC_MUX_UI_LSB;
1644
 
1645
#ifdef RETRY_MODE_ENABLED
1646
                found_new_history_entry_size_m1 = fifo_user_packet_with_data_m1;
1647
                found_new_history_entry = true;
1648
#endif
1649
 
1650
                if(local_priority.read())
1651
                        found_local_packet_issued = !isChain;
1652
                else
1653
                        found_next_fairness_vc_reserved[fifo_user_packet_vc.read()] = isChain;
1654
 
1655
                found_next_data_cnt = fifo_user_packet_data_count_m1.read();
1656
                found_next_has_data = fifo_user_packet_data_asociated.read();
1657
                set_found_sent_type(fifo_user_packet_vc.read(),fifo_user_packet_data_asociated.read());
1658
        }
1659
        else  {
1660
#ifdef RETRY_MODE_ENABLED
1661
                found_next_calculate_crc = false;
1662
                found_next_calculate_nop_crc = true;
1663
#endif
1664
                found_fc_ctr_mux = FC_MUX_NOP;
1665
                found_fc_nop_sent = !disconnect;
1666
                found_generate_disconnect_nop = disconnect;
1667
 
1668
                //If the link needs to be disconnected
1669
                if(disconnect){
1670
#ifdef RETRY_MODE_ENABLED
1671
                        //In retry mode, we initiate a retry sequence
1672
                        if(csr_retry.read()){
1673
                                found_next_state = RETRY_SEND_DISCONNECT;
1674
                        }
1675
                        else
1676
#endif
1677
                        //Otherwise we just go to standard LDTSTOP disconnect
1678
                        {
1679
                                found_next_state = LDTSTOP_DISCONNECT;
1680
                        }
1681
                }
1682
                //Send nop
1683
                else{
1684
                        found_next_state = NOP_SENT;
1685
                }
1686
        }
1687
}
1688
 
1689
 
1690
#ifdef RETRY_MODE_ENABLED
1691
 
1692
void flow_control_l3::set_foundh_sent_type (VirtualChannel vc , bool data) {
1693
 
1694
        //comment for Reference, do not uncomment
1695
        //or uncomment and define an enum somewhere
1696
        //enum VirtualChannel {VC_POSTED,VC_NON_POSTED,VC_RESPONSE,VC_NONE};
1697
        //   ResponseData;      //bit 0
1698
        //       Response;              //bit 1
1699
        //       NonPostData;   //bit 2
1700
        //       NonPostCmd;    //bit 3
1701
        //       PostData;              //bit 4 
1702
        //       PostCmd;               //bit 5
1703
 
1704
        switch (vc) {
1705
 
1706
        case VC_POSTED :
1707
                if (data == true)
1708
                        foundh_current_sent_type = "110000";
1709
                else
1710
                        foundh_current_sent_type = "100000";
1711
                break;
1712
 
1713
        case VC_NON_POSTED :
1714
                if (data == true)
1715
                        foundh_current_sent_type = "001100";
1716
                else
1717
                        foundh_current_sent_type = "001000";
1718
                break;
1719
 
1720
        case VC_RESPONSE :
1721
                if (data == true)
1722
                        foundh_current_sent_type = "000011";
1723
                else
1724
                        foundh_current_sent_type = "000010";
1725
                break;
1726
 
1727
        default :
1728
                foundh_current_sent_type = "000000";
1729
                break;
1730
 
1731
        }
1732
 
1733
}
1734
#endif
1735
 
1736
 
1737
void flow_control_l3::set_found_sent_type (VirtualChannel vc , bool data) {
1738
 
1739
        //comment for Reference, do not uncomment
1740
        //or uncomment and define an enum somewhere
1741
        //enum VirtualChannel {VC_POSTED,VC_NON_POSTED,VC_RESPONSE,VC_NONE};
1742
        //   ResponseData;      //bit 0
1743
        //       Response;              //bit 1
1744
        //       NonPostData;   //bit 2
1745
        //       NonPostCmd;    //bit 3
1746
        //       PostData;              //bit 4 
1747
        //       PostCmd;               //bit 5
1748
 
1749
        switch (vc) {
1750
 
1751
        case VC_POSTED :
1752
                if (data == true)
1753
                        found_current_sent_type = "110000";
1754
                else
1755
                        found_current_sent_type = "100000";
1756
                break;
1757
 
1758
        case VC_NON_POSTED :
1759
                if (data == true)
1760
                        found_current_sent_type = "001100";
1761
                else
1762
                        found_current_sent_type = "001000";
1763
                break;
1764
 
1765
        case VC_RESPONSE :
1766
                if (data == true)
1767
                        found_current_sent_type = "000011";
1768
                else
1769
                        found_current_sent_type = "000010";
1770
                break;
1771
 
1772
        default :
1773
                found_current_sent_type = "000000";
1774
                break;
1775
 
1776
        }
1777
 
1778
}
1779
 
1780
bool flow_control_l3::verify_buffer_status (VirtualChannel vc , bool data ){
1781
 
1782
        //comment for Reference, do not uncomment
1783
        //enum VirtualChannel {VC_POSTED,VC_NON_POSTED,VC_RESPONSE,VC_NONE};
1784
        //   ResponseData;      //bit 0
1785
        //       Response;              //bit 1
1786
        //       NonPostData;   //bit 2
1787
        //       NonPostCmd;    //bit 3
1788
        //       PostData;              //bit 4 
1789
        //       PostCmd;               //bit 5
1790
 
1791
 
1792
        switch (vc) {
1793
 
1794
        case VC_POSTED :
1795
                if (data == true)
1796
                        return  (fwd_next_node_buffer_status_ro.read()[BUF_STATUS_P_DATA] == true &&
1797
                        fwd_next_node_buffer_status_ro.read()[BUF_STATUS_P_CMD] == true);
1798
                else
1799
                        return  (fwd_next_node_buffer_status_ro.read()[BUF_STATUS_P_CMD] == true);
1800
                break;
1801
 
1802
        case VC_NON_POSTED :
1803
                if (data == true)
1804
                        return  (fwd_next_node_buffer_status_ro.read()[BUF_STATUS_NP_DATA] == true &&
1805
                        fwd_next_node_buffer_status_ro.read()[BUF_STATUS_NP_CMD] == true);
1806
                else
1807
                        return  (fwd_next_node_buffer_status_ro.read()[BUF_STATUS_NP_CMD] == true);
1808
 
1809
                break;
1810
 
1811
        case VC_RESPONSE :
1812
                if (data == true)
1813
                        return  (fwd_next_node_buffer_status_ro.read()[BUF_STATUS_R_DATA] == true &&
1814
                        fwd_next_node_buffer_status_ro.read()[BUF_STATUS_R_CMD] == true);
1815
                else
1816
                        return  (fwd_next_node_buffer_status_ro.read()[BUF_STATUS_R_CMD] == true);
1817
                break;
1818
 
1819
        default :
1820
                return false;
1821
 
1822
 
1823
        }
1824
 
1825
}
1826
 
1827
void flow_control_l3::go_NOP_SENT(){
1828
        fc_ctr_mux = FC_MUX_NOP;
1829
        fc_nop_sent = true;
1830
        next_state = NOP_SENT;
1831
        next_fc_lctl_lk = true;
1832
        next_fc_hctl_lk = true;
1833
#ifdef RETRY_MODE_ENABLED
1834
        next_calculate_nop_crc = true;
1835
#endif
1836
}
1837
 
1838
 
1839
void flow_control_l3::go_NOP_SENT_IN_FWD(){
1840
        fc_ctr_mux = FC_MUX_NOP;
1841
        fc_nop_sent = true;
1842
        next_state = NOP_SENT_IN_FWD;
1843
        next_fc_lctl_lk = true;
1844
        next_fc_hctl_lk = true;
1845
#ifdef RETRY_MODE_ENABLED
1846
        next_calculate_nop_crc = true;
1847
#endif
1848
}
1849
 
1850
void flow_control_l3::go_NOP_SENT_IN_USER(){
1851
        fc_ctr_mux = FC_MUX_NOP;
1852
        fc_nop_sent = true;
1853
        next_state = NOP_SENT_IN_USER;
1854
        next_fc_lctl_lk = true;
1855
        next_fc_hctl_lk = true;
1856
#ifdef RETRY_MODE_ENABLED
1857
        next_calculate_nop_crc = true;
1858
#endif
1859
}
1860
 
1861
void flow_control_l3::go_NOP_SENT_IN_EH(){
1862
        fc_ctr_mux = FC_MUX_NOP;
1863
        fc_nop_sent = true;
1864
        next_state = NOP_SENT_IN_EH;
1865
        next_fc_lctl_lk = true;
1866
        next_fc_hctl_lk = true;
1867
#ifdef RETRY_MODE_ENABLED
1868
        next_calculate_nop_crc = true;
1869
#endif
1870
}
1871
 
1872
void flow_control_l3::go_NOP_SENT_IN_CSR(){
1873
        fc_ctr_mux = FC_MUX_NOP;
1874
        fc_nop_sent = true;
1875
        next_state = NOP_SENT_IN_CSR;
1876
        next_fc_lctl_lk = true;
1877
        next_fc_hctl_lk = true;
1878
#ifdef RETRY_MODE_ENABLED
1879
        next_calculate_nop_crc = true;
1880
#endif
1881
}
1882
 
1883
void flow_control_l3::go_FWD_DATA_SENT(){
1884
        next_fc_lctl_lk = false;
1885
        next_fc_hctl_lk = false;
1886
        fc_ctr_mux = FC_MUX_DB_DATA;
1887
        next_data_cnt = data_cnt.read() - 1;
1888
        next_state = FWD_DATA_SENT;
1889
        next_has_data = data_cnt.read() != 0;
1890
        fwd_erase_db = data_cnt.read() == 0;
1891
 
1892
        fwd_read_db = true;
1893
#ifdef RETRY_MODE_ENABLED
1894
        next_calculate_crc = true;
1895
#endif
1896
}
1897
 
1898
void flow_control_l3::go_USER_DATA_SENT(){
1899
        next_fc_lctl_lk = false;
1900
        next_fc_hctl_lk = false;
1901
        fc_ctr_mux = FC_MUX_UI_DATA;
1902
        next_data_cnt = data_cnt.read() - 1;
1903
        next_state = USER_DATA_SENT;
1904
        next_has_data = data_cnt.read() != 0;
1905
        fc_consume_data_ui = true;
1906
#ifdef RETRY_MODE_ENABLED
1907
        next_calculate_crc = true;
1908
#endif
1909
}
1910
 
1911
void flow_control_l3::go_ERROR_DATA_SENT(){
1912
        next_fc_lctl_lk = false;
1913
        next_fc_hctl_lk = false;
1914
        fc_ctr_mux = FC_MUX_EH;
1915
        next_data_cnt = data_cnt.read() - 1;
1916
        next_state = ERROR_DATA_SENT;
1917
        next_has_data = data_cnt.read() != 0;
1918
        fc_ack_eh = true;
1919
#ifdef RETRY_MODE_ENABLED
1920
        next_calculate_crc = true;
1921
#endif
1922
}
1923
 
1924
void flow_control_l3::go_CSR_DATA_SENT(){
1925
        next_fc_lctl_lk = false;
1926
        next_fc_hctl_lk = false;
1927
        fc_ctr_mux = FC_MUX_CSR;
1928
        next_data_cnt = data_cnt.read() - 1;
1929
        next_state = CSR_DATA_SENT;
1930
        next_has_data = data_cnt.read() != 0;
1931
        fc_ack_csr = true;
1932
#ifdef RETRY_MODE_ENABLED
1933
        next_calculate_crc = true;
1934
#endif
1935
}
1936
 
1937
void flow_control_l3::go_LDTSTOP_DISCONNECT(){
1938
        //next_fc_disconnect_lk = false;
1939
        fc_ctr_mux = FC_MUX_NOP; //32 bits NOP
1940
        next_fc_lctl_lk = true;
1941
        next_fc_hctl_lk = true;
1942
        generate_disconnect_nop = true;
1943
 
1944
        next_state = LDTSTOP_DISCONNECT;
1945
#ifdef RETRY_MODE_ENABLED
1946
        next_calculate_nop_crc = false;
1947
#endif
1948
}
1949
 
1950
 
1951
#ifdef RETRY_MODE_ENABLED
1952
 
1953
void flow_control_l3::go_RETRY_NOP_SENT(){
1954
        fc_ctr_mux = FC_MUX_NOP;
1955
        fc_nop_sent = true;
1956
        next_state = RETRY_NOP_SENT;
1957
        next_fc_lctl_lk = true;
1958
        next_fc_hctl_lk = true;
1959
        next_calculate_nop_crc = true;
1960
}
1961
 
1962
void flow_control_l3::go_RETRY_NOP_SENT_IN_DATA(){
1963
        fc_ctr_mux = FC_MUX_NOP;
1964
        fc_nop_sent = true;
1965
        next_state = RETRY_NOP_SENT_IN_DATA;
1966
        next_fc_lctl_lk = true;
1967
        next_fc_hctl_lk = true;
1968
        next_calculate_nop_crc = true;
1969
}
1970
 
1971
void flow_control_l3::go_NOP_CRC_SENT_IN_FWD(){
1972
        next_select_nop_crc_output = true;
1973
        fc_nop_sent = false;
1974
        next_state = NOP_CRC_SENT_IN_FWD;
1975
        next_fc_lctl_lk = true;
1976
        next_fc_hctl_lk = false;
1977
}
1978
 
1979
void flow_control_l3::go_SEND_CMD_CRC(){
1980
        next_state = SEND_CMD_CRC;
1981
        next_select_crc_output = true;
1982
        next_fc_lctl_lk = true;
1983
        next_fc_hctl_lk = false;
1984
}
1985
 
1986
void flow_control_l3::go_RETRY_SEND_CMD_CRC(){
1987
        next_state = RETRY_SEND_CMD_CRC;
1988
        next_select_crc_output = true;
1989
        next_fc_lctl_lk = true;
1990
        next_fc_hctl_lk = false;
1991
}
1992
 
1993
void flow_control_l3::go_RETRY_SEND_CMD_CRC_DATA(){
1994
        next_state = RETRY_SEND_CMD_CRC;
1995
        next_select_crc_output = true;
1996
        next_fc_lctl_lk = false;
1997
        next_fc_hctl_lk = true;
1998
}
1999
 
2000
 
2001
void flow_control_l3::go_RETRY_DATA_SENT(){
2002
        next_fc_lctl_lk = false;
2003
        next_fc_hctl_lk = false;
2004
        fc_ctr_mux = FC_MUX_HISTORY;
2005
        next_data_cnt = data_cnt.read() - 1;
2006
        next_state = RETRY_DATA_SENT;
2007
        next_has_data = data_cnt.read() != 0;
2008
 
2009
        consume_history = true;
2010
        next_calculate_crc = true;
2011
}
2012
 
2013
void flow_control_l3::go_SEND_DATA_CRC(){
2014
        //fc_ctr_mux = FC_MUX_CRC;
2015
        next_state = SEND_DATA_CRC;
2016
        next_fc_lctl_lk = false;
2017
        next_fc_hctl_lk = true;
2018
        next_select_crc_output = true;
2019
}
2020
 
2021
 
2022
void flow_control_l3::go_RETRY_SEND_DISCONNECT(){
2023
        fc_ctr_mux = FC_MUX_NOP; //32 bits NOP
2024
        next_fc_lctl_lk = true;
2025
        next_fc_hctl_lk = true;
2026
        generate_disconnect_nop = true;
2027
        next_calculate_nop_crc = true;
2028
 
2029
        next_state = RETRY_SEND_DISCONNECT_CRC;
2030
}
2031
 
2032
void flow_control_l3::go_next_retry_state(){
2033
        fc_ctr_mux = foundh_fc_ctr_mux;
2034
        fc_nop_sent = foundh_fc_nop_sent;
2035
        next_state = foundh_next_state;
2036
        next_fc_lctl_lk = foundh_next_fc_lctl_lk;
2037
        next_fc_hctl_lk = foundh_next_fc_hctl_lk;
2038
        next_calculate_nop_crc = foundh_next_calculate_nop_crc;
2039
        next_calculate_crc = foundh_next_calculate_crc;
2040
        next_data_cnt = foundh_next_data_cnt;
2041
        next_has_data = foundh_next_has_data;
2042
        current_sent_type = foundh_current_sent_type;
2043
        consume_history = foundh_consume_history;
2044
}
2045
 
2046
void flow_control_l3::find_next_retry_state(){
2047
 
2048
        //Find if sending a nop has been requested by other modules
2049
        bool nop_req;
2050
        if (ro_nop_req_fc ==  true || db_nop_req_fc ==  true || nop_next_to_send == true )
2051
                nop_req = true;
2052
        else
2053
                nop_req  = false;
2054
 
2055
        sc_bv<6> history_cmd_bits = history_packet.read().range(5,0);
2056
 
2057
        PacketCommand history_cmd = getPacketCommand(history_cmd_bits);
2058
        VirtualChannel history_vc = getVirtualChannel(sc_bv<64>(history_packet.read()),history_cmd);
2059
        bool history_data_associated = hasDataAssociated(history_cmd);
2060
        bool enough_buffers = verify_buffer_status(history_vc,history_data_associated);
2061
        bool dword_packet = isDwordPacket((sc_bv<64>)history_packet.read(),history_cmd);
2062
 
2063
        //Brought before the if/elsif statement to try to accelerate
2064
        //the combinatorial path
2065
        foundh_consume_history = (ldtstopx.read() && !nop_req) &&
2066
                (!history_playback_done.read() && enough_buffers);
2067
 
2068
        foundh_fc_nop_sent = false;
2069
        foundh_next_fc_lctl_lk = true;
2070
        foundh_next_fc_hctl_lk = true;
2071
        foundh_next_calculate_nop_crc = false;
2072
        foundh_next_calculate_crc = false;
2073
        foundh_next_data_cnt = 0;
2074
        foundh_next_has_data = false;
2075
        foundh_current_sent_type = "000000";
2076
        foundh_generate_disconnect_nop = false;
2077
 
2078
        if(ldtstopx.read() == false || retry_disconnect_initiated.read()){
2079
                foundh_next_calculate_nop_crc = true;
2080
                foundh_next_state = RETRY_SEND_DISCONNECT;
2081
                foundh_fc_ctr_mux = FC_MUX_NOP;
2082
                foundh_generate_disconnect_nop = true;
2083
                foundh_next_calculate_nop_crc = true;
2084
        }
2085
        else if(!history_playback_done.read() && enough_buffers && !nop_req){
2086
                set_foundh_sent_type(history_vc,history_data_associated);
2087
                foundh_next_data_cnt = getDataLengthm1(sc_bv<64>(history_packet.read()));
2088
                foundh_next_has_data = history_data_associated;
2089
                foundh_fc_ctr_mux = FC_MUX_HISTORY;
2090
                foundh_next_calculate_crc = true;
2091
 
2092
                //Brought before the if/elsif statement to try to accelerate
2093
                //the combinatorial path
2094
                //foundh_consume_history = dword_packet;
2095
 
2096
                if (dword_packet){
2097
                        foundh_next_state = RETRY_CMD32_SENT;
2098
                }
2099
                else{
2100
                        foundh_next_state = RETRY_CMD64_FIRST_SENT;
2101
                }
2102
        }
2103
        else{
2104
                if(!history_playback_done.read())
2105
                        foundh_next_state = RETRY_NOP_SENT;
2106
                else
2107
                        foundh_next_state = NOP_SENT;
2108
 
2109
                foundh_fc_ctr_mux = FC_MUX_NOP;
2110
                foundh_fc_nop_sent = true;
2111
                foundh_next_calculate_nop_crc = true;
2112
        }
2113
}
2114
 
2115
#endif
2116
 
2117
#ifndef SYSTEMC_SIM
2118
 
2119
#include "../core_synth/synth_control_packet.cpp"
2120
 
2121
#endif
2122
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.