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

Subversion Repositories ht_tunnel

[/] [ht_tunnel/] [trunk/] [bench/] [vc_ht_tunnel_l1_tb/] [LogicalLayer.cpp] - Blame information for rev 19

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 acastong
//LogicalLayer.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
 *   Ami Castonguay <acastong@grm.polymtl.ca>
25
 *
26
 * Alternatively, the contents of this file may be used under the terms
27
 * of the Polytechnique HyperTransport Tunnel IP Core Source Code License
28
 * (the  "PHTICSCL License", see the file PHTICSCL.txt), in which case the
29
 * provisions of PHTICSCL License are applicable instead of those
30
 * above. If you wish to allow use of your version of this file only
31
 * under the terms of the PHTICSCL License and not to allow others to use
32
 * your version of this file under the MPL, indicate your decision by
33
 * deleting the provisions above and replace them with the notice and
34
 * other provisions required by the PHTICSCL License. If you do not delete
35
 * the provisions above, a recipient may use your version of this file
36
 * under either the MPL or the PHTICSCL License."
37
 *
38
 * ***** END LICENSE BLOCK ***** */
39
 
40
#include "../core/PacketContainer.h"
41
#include "../core/InfoPacket.h"
42
#include "../core/RequestPacket.h"
43
#include "LogicalLayer.h"
44
 
45
 
46
const int LogicalLayer::PER_PACKET_CRC_POLY = 0x04C11DB7;
47
const int LogicalLayer::MAX_BUFFERS = 8;
48
 
49
#include <iostream>
50
 
51
using namespace std;
52
 
53
LogicalLayer::LogicalLayer(sc_module_name name) : sc_module(name){
54
        SC_THREAD(reset_thread);
55
        sensitive_pos(clk);
56
        sensitive_neg(resetx);
57
 
58
        inter = NULL;
59
        physicalLayer = NULL;
60
 
61
        packetIdCounter = 0;
62
        retry_mode = false;
63
        retry_mode_after_reset = false;
64
        initiate_retry_disconnect = false;
65
 
66
        receivedPacket = NULL;
67
        receivedDataCount = 0;
68
        receive_state = RECEIVE_IDLE;
69
        rx_ack_value = 0;
70
        rx_retry_waiting_for_nop = false;
71
 
72
 
73
        nopSendPacket = NULL;
74
        currentSendPacket.data = NULL;
75
        currentSendPacket.packet = NULL;
76
        disconNop = false;
77
        ignoreIncoming = false;
78
        displayReceivedDword = false;
79
 
80
        for(int n = 0; n < 3; n++){
81
                nextNodeCommandBuffersFree[n] = 0;
82
                nextNodeDataBuffersFree[n] = 0;
83
 
84
                commandBuffersAdvertised[n] = 0;
85
                dataBuffersAdvertised[n] = 0;
86
                commandBuffersFree[n] = MAX_BUFFERS;
87
                dataBuffersFree[n] = MAX_BUFFERS;
88
        }
89
}
90
 
91
LogicalLayer::~LogicalLayer(){
92
        delete nopSendPacket;
93
        //currentSendPacket is deleted after it's used, no need to delete immediately
94
        delete receivedPacket;
95
        //Packets are both in history and packetQueue.  Clear packetQueue and delete 
96
        //the entries in packetHistory
97
        packetQueue.clear();
98
 
99
        //Delete packets in the history
100
        deque<PacketAndData>::iterator i;
101
        for(i = packetHistory.begin(); i != packetHistory.end();i++){
102
                delete (*i).packet;
103
                delete [] (*i).data;
104
        }
105
}
106
 
107
void LogicalLayer::reset_thread(){
108
        while(true){
109
                if(!resetx.read()){
110
                        retry_mode = retry_mode_after_reset;
111
 
112
                        packetIdCounter = 0;
113
                        receivedDataCount = 0;
114
                        rx_ack_value = 0;
115
                        receive_state = RECEIVE_IDLE;
116
 
117
                        //Packets are both in history and packetQueue.  Clear packetQueue and delete 
118
                        //the entries in packetHistory
119
                        packetQueue.clear();
120
 
121
                        //Delete packets in the history
122
                        deque<PacketAndData>::iterator i;
123
                        for(i = packetHistory.begin(); i != packetHistory.end();i++){
124
                        delete (*i).packet;
125
                        delete [] (*i).data;
126
                        }
127
                        packetHistory.clear();
128
 
129
                        for(int n = 0; n < 3; n++){
130
                                nextNodeCommandBuffersFree[n] = 0;
131
                                nextNodeDataBuffersFree[n] = 0;
132
 
133
                                commandBuffersAdvertised[n] = 0;
134
                                dataBuffersAdvertised[n] = 0;
135
                        }
136
                }
137
                wait();
138
        }
139
}
140
 
141
void LogicalLayer::receivedDwordEvent(sc_bv<32> &dword,bool lctl,bool hctl){
142
        if(displayReceivedDword) cout << "Received dword: " << dword.to_string(SC_HEX) << endl;
143
 
144
        //If reset or during a retry sequence, ignore the received data
145
        if(!resetx.read() || initiate_retry_disconnect || ignoreIncoming)return;
146
 
147
        if(receive_state == RECEIVE_SECOND_DWORD){
148
                //Set the seconde dword of the packet (it only had the first dword set)
149
                receivedPacket->setSecondDword(dword);
150
 
151
                //If there is any data with that packet, go into receiving data state
152
                if(receivedPacket->hasDataAssociated()){
153
                        receivedDataCount = 0;
154
                        receive_state = RECEIVE_DATA;
155
                }
156
                else{
157
                        //If in retry mode, start by receiving the CRC
158
                        if(retry_mode){
159
                                receive_state = RECEIVE_CRC;
160
                        }
161
                        else{
162
                                //Generate event of received packet and wait for next packet
163
                                receive_state = RECEIVE_IDLE;
164
                                inter->receivedHtPacketEvent(receivedPacket,NULL,this);
165
                                updateRxBufferCount(receivedPacket);
166
                        }
167
                }
168
        }
169
 
170
 
171
        else if(receive_state == RECEIVE_DATA){
172
                //If CTL is activated, it is a nop inside data
173
                if(lctl || hctl){
174
                        if(retry_mode){
175
                                firstReceivedDword = dword;
176
                                receive_state = RECEIVE_NOP_CRC;
177
                        }
178
                        else handleNopPacket(dword);
179
                }
180
                else{
181
                        //Set the received data
182
                        receivedData[receivedDataCount] = dword.to_int();
183
 
184
                        //Check if receiving data is done
185
                        if(receivedDataCount++ == receivedPacket->getDataLengthm1()){
186
                                if(retry_mode){
187
                                        receive_state = RECEIVE_CRC;
188
                                }
189
                                else{
190
                                        //When it's done, generate event that packet is received
191
                                        inter->receivedHtPacketEvent(receivedPacket,receivedData,this);
192
                                        updateRxBufferCount(receivedPacket);
193
                                        receive_state = RECEIVE_IDLE;
194
                                }
195
                        }
196
                }
197
        }
198
 
199
 
200
        else if(receive_state == RECEIVE_CRC){
201
                //Calculate the packet CRC
202
                int crc = calcultatePacketCrc(receivedPacket,receivedData);
203
 
204
                //CRC is inversed before being sent out, check if it's invalid
205
                if(~crc != dword.to_int()){
206
                        cout << "Wrong CRC received for packet: " << (*receivedPacket) << endl;
207
                        initiateRetrySequence();
208
                }
209
                /**If valid, handle the packet*/
210
                else{
211
                        //If nop, update the buffer count
212
                        if(receivedPacket->getPacketCommand() == NOP)
213
                                handleNopPacket(firstReceivedDword);
214
                        //Otherwise, notify of received packet and update ack value
215
                        else{
216
                                rx_ack_value++;
217
                                inter->receivedHtPacketEvent(receivedPacket,receivedData,this);
218
                                updateRxBufferCount(receivedPacket);
219
                        }
220
                }
221
                receive_state = RECEIVE_IDLE;
222
        }
223
 
224
        //RECEIVE_NOP_CRC is a state for receiving nops inside data packets.  Check
225
        //if the crc is correct, handle the nop packet and go back to receiving data,
226
        //or initiate retry sequence if crc is incorrect
227
        else if(receive_state == RECEIVE_NOP_CRC){
228
                PacketContainer c = ControlPacket::createPacketFromDword(firstReceivedDword);
229
                int crc = calcultatePacketCrc(c.getPacketRef(),NULL);
230
                if(~crc != dword.to_int()) initiateRetrySequence();
231
                else handleNopPacket(firstReceivedDword);
232
                receive_state = RECEIVE_DATA;
233
        }
234
 
235
        //Otherwise in IDLE state
236
        else{
237
                //store the received dword
238
                firstReceivedDword = dword;
239
 
240
                //Create a packet object from the dword
241
                PacketContainer c = ControlPacket::createPacketFromDword(dword);
242
 
243
                //If its a nop
244
                if(c->getPacketCommand() == NOP){
245
                        if(retry_mode){
246
                                //Delete any previously allocated packet
247
                                delete receivedPacket;
248
                                receivedPacket = c.giveControl();
249
                                receive_state = RECEIVE_CRC;
250
                        }
251
                        else handleNopPacket(dword);
252
                }
253
                //If if only has one dword
254
                else if(c->isDwordPacket()){
255
                        //If it has any data associated to it, go to receiving data state
256
                        if(c->hasDataAssociated()){
257
                                receive_state = RECEIVE_DATA;
258
                                receivedDataCount = 0;
259
                                //Delete any previously allocated packet
260
                                delete receivedPacket;
261
                                receivedPacket = c.giveControl();
262
                        }
263
                        else{
264
                                //packet received, either receive CRC if in retry mode or generate event
265
                                if(retry_mode){
266
                                        receive_state = RECEIVE_CRC;
267
                                        //Delete any previously allocated packet
268
                                        delete receivedPacket;
269
                                        receivedPacket = c.giveControl();
270
                                }
271
                                else{
272
                                        inter->receivedHtPacketEvent(c.getPacketRef(),NULL,this);
273
                                        updateRxBufferCount(c.getPacketRef());
274
                                }
275
                        }
276
                }
277
                //If not dword packet, go to receive second dword state
278
                else{
279
                        receive_state = RECEIVE_SECOND_DWORD;
280
                        delete receivedPacket;
281
                        receivedPacket = c.giveControl();
282
                }
283
        }
284
}
285
 
286
void LogicalLayer::handleNopPacket(sc_bv<32> &dword){
287
        //Create a nop packet
288
        NopPacket* nop = new NopPacket(dword);
289
 
290
        //Update the next node buffer free count
291
        nextNodeCommandBuffersFree[VC_POSTED] += (int)nop->getFreeBufPostedCmd();
292
        nextNodeDataBuffersFree[VC_POSTED] += (int)nop->getFreeBufPostedData();
293
        nextNodeCommandBuffersFree[VC_NON_POSTED] += (int)nop->freeBufNonPostedCmd();
294
        nextNodeDataBuffersFree[VC_NON_POSTED] += (int)nop->freeBufNonPostedData();
295
        nextNodeCommandBuffersFree[VC_RESPONSE] += (int)nop->freeBufResponseCmd();
296
        nextNodeDataBuffersFree[VC_RESPONSE] += (int)nop->freeBufResponseData();
297
        packetIdCounter = (int)nop->getRxNextPacketToAck();
298
 
299
        //If in retry mode, delete old entries in the history
300
        if(retry_mode){
301
                bool done = packetHistory.empty();
302
                while(!done){
303
                        if(((packetIdCounter - packetHistory.front().id + 256) % 256) < 128){
304
                                delete packetHistory.front().packet;
305
                                delete [] packetHistory.front().data;
306
                                packetHistory.pop_front();
307
                                done = packetHistory.empty();
308
                        }
309
                        else done = true;
310
                }
311
        }
312
}
313
 
314
void LogicalLayer::dwordToSendRequested(sc_bv<32> &dword,bool &lctl,bool &hctl){
315
        //during reset, don't send anything
316
        if(!resetx.read()) return;
317
 
318
        if(send_state == SEND_SECOND_DWORD){
319
                //get the second dword from the packet
320
                dword = currentSendPacket.packet->getVector().range(63,32);
321
                //Command packet have CTL=1
322
                lctl = true; hctl = true;
323
 
324
                //Go to the correct state depending on packet type
325
                if(currentSendPacket.packet->hasDataAssociated()){
326
                        sendDataCount = 0;
327
                        send_state = SEND_DATA;
328
                }
329
                else{
330
                        if(retry_mode){
331
                                send_state = SEND_CRC;
332
                        }
333
                        /** In retry mode, packets are stored in history and can be
334
                                deleted when history is acknowleged.  When not in retry mode,
335
                                this does not happen so delete immediately after send*/
336
                        else{
337
                                delete currentSendPacket.packet;
338
                                send_state = SEND_IDLE;
339
                        }
340
                }
341
        }
342
        //If sending an address extension.  This is not supported by the tunnel but
343
        //should be handle cleanly by responding with an error response.  If here,
344
        //the address extension has already been sent, now send the actual packet
345
        else if(send_state == SEND_ADDR_EXT){
346
                //send first dword
347
                dword = currentSendPacket.packet->getVector().range(31,0);
348
 
349
                //go to correct state depending on packet content
350
                bool has_data = currentSendPacket.packet->hasDataAssociated();
351
                VirtualChannel vc = currentSendPacket.packet->getVirtualChannel();
352
 
353
                if(!currentSendPacket.packet->isDwordPacket()){
354
                        send_state = SEND_SECOND_DWORD;
355
                }
356
                else if(has_data){
357
                        send_state = SEND_DATA;
358
                }
359
                else if(retry_mode){
360
                        send_state = SEND_CRC;
361
                }
362
                /** In retry mode, packets are stored in history and can be
363
                        deleted when history is acknowleged.  When not in retry mode,
364
                        this does not happen so delete immediately after send*/
365
                else{
366
                        send_state = SEND_IDLE;
367
                        delete currentSendPacket.packet;
368
                }
369
        }
370
        else if(send_state == SEND_DATA){
371
                //Check if sending a nop in the middle of the data is necessary
372
                if(isSendingNopRequired()){
373
                        //Delete any previous nop packet
374
                        delete nopSendPacket;
375
                        nopSendPacket = generateNopPacket();
376
                        dword = nopSendPacket->getVector().range(31,0);
377
                        lctl = true; hctl = true;
378
                        if(retry_mode){
379
                                send_state = SEND_NOP_CRC;
380
                        }
381
                }
382
                //otherwise keep sending data
383
                else{
384
                        lctl = false; hctl = false;
385
                        dword = currentSendPacket.data[sendDataCount];
386
                        if(sendDataCount++ == currentSendPacket.packet->getDataLengthm1()){
387
                                if(retry_mode){
388
                                        send_state = SEND_CRC;
389
                                }
390
                                /** In retry mode, packets are stored in history and can be
391
                                        deleted when history is acknowleged.  When not in retry mode,
392
                                        this does not happen so delete immediately after send*/
393
                                else{
394
                                        send_state = SEND_IDLE;
395
                                        delete currentSendPacket.packet;
396
                                        delete[] currentSendPacket.data;
397
                                }
398
                        }
399
                }
400
        }
401
        else if(send_state == SEND_NOP_CRC){
402
                int crc = calcultatePacketCrc(nopSendPacket,NULL);
403
                dword = ~crc;
404
                lctl = true; hctl = false;
405
                send_state = SEND_DATA;
406
        }
407
        else if(send_state == SEND_CRC){
408
                int crc = calcultatePacketCrc(currentSendPacket.packet,currentSendPacket.data);
409
                dword = ~crc;
410
                //Value of lctl and hctl depends on if the packet has data or not
411
                if(currentSendPacket.packet->hasDataAssociated()){
412
                        lctl = false; hctl = true;
413
                }
414
                else{
415
                        lctl = true; hctl = false;
416
                }
417
                send_state = SEND_IDLE;
418
 
419
                //If what was just sent a disconnect nop, then we must complete the retry sequence
420
                if(disconNop){
421
                        //reset retry initiation variables
422
                        initiate_retry_disconnect = false;
423
                        disconNop = false;
424
 
425
                        //Start the retry disconnect and reconnect on the physical level
426
                        physicalLayer->retryDisconnectAndReconnect();
427
 
428
                        //Clear current list of packets to send
429
                        packetQueue.clear();
430
                        packetQueue = packetHistory;
431
                        for(int n = 0; n < 3; n++){
432
                                commandBuffersAdvertised[n] = 0;
433
                                dataBuffersAdvertised[n] = 0;
434
                        }
435
                }
436
        }
437
        else{
438
                //If a retry sequence should be initiated
439
                if(initiate_retry_disconnect){
440
                        //Generate a disconnect nop
441
                        delete nopSendPacket;
442
                        nopSendPacket = new NopPacket(0,0,0,0,0,0,
443
                          true, false, false, 0);
444
                        currentSendPacket.packet = nopSendPacket;
445
                        currentSendPacket.data = NULL;
446
                        disconNop = true;
447
 
448
                        //Send that disconnect nop
449
                        dword = nopSendPacket->getVector().range(31,0); lctl = true; hctl = true;
450
                        send_state = SEND_CRC;
451
                }
452
                //Send nop if it is required (for buffer reasons, or if nothing else to send|)
453
                else if(isSendingNopRequired() || packetQueue.empty()){
454
                        //Delete any previous nop packet
455
                        delete nopSendPacket;
456
                        //create a new not
457
                        nopSendPacket = generateNopPacket();
458
                        currentSendPacket.packet = nopSendPacket;
459
                        currentSendPacket.data = NULL;
460
 
461
                        //Send the nop
462
                        dword = currentSendPacket.packet->getVector().range(31,0);
463
                        lctl = true; hctl = true;
464
                        if(retry_mode){
465
                                send_state = SEND_CRC;
466
                        }
467
                }
468
                //Otherwise, attempt to send the packet on top of the queue
469
                else{
470
 
471
                        //Check if the top packet can be sent : check if the next
472
                        //node has sufficient buffers to receive it
473
                        ControlPacket * cmd = packetQueue.front().packet;
474
                        bool has_data = cmd->hasDataAssociated();
475
                        VirtualChannel vc = cmd->getVirtualChannel();
476
                        bool canBeSent = false;
477
                        if(vc <= 2){
478
                                canBeSent = nextNodeCommandBuffersFree[vc] &&
479
                                        (nextNodeDataBuffersFree[vc] || !has_data);
480
                        }
481
                        bool delete_command = false;
482
 
483
                        //If it can be sent, go to the appropriate state to send it
484
                        if(cmd->getPacketCommand() == NOP){
485
                                currentSendPacket = packetQueue.front();
486
                                packetQueue.pop_front();
487
                                if(retry_mode){
488
                                        send_state = SEND_CRC;
489
                                }
490
                                else delete_command = true;
491
                        }
492
                        if(canBeSent){
493
                                nextNodeCommandBuffersFree[vc]--;
494
                                if(has_data) nextNodeDataBuffersFree[vc]--;
495
 
496
                                currentSendPacket = packetQueue.front();
497
                                packetQueue.pop_front();
498
                                if(cmd->getPacketCommand() == ADDR_EXT){
499
                                        send_state = SEND_ADDR_EXT;
500
                                }
501
                                else if(!cmd->isDwordPacket()){
502
                                        send_state = SEND_SECOND_DWORD;
503
                                }
504
                                else if(has_data){
505 18 acastong
                                        sendDataCount = 0;
506 2 acastong
                                        send_state = SEND_DATA;
507
                                }
508
                                else if(retry_mode){
509
                                        send_state = SEND_CRC;
510
                                }
511
                                /** In retry mode, packets are stored in history and can be
512
                                        deleted when history is acknowleged.  When not in retry mode,
513
                                        this does not happen so delete immediately after send*/
514
                                else delete_command = true;
515
                        }
516
                        //Otherwise, send a nop
517
                        else{
518
                                //cout << "Not enough buffers, sending nop instead" << endl;
519
                                delete nopSendPacket;
520
                                nopSendPacket = generateNopPacket();
521
                                currentSendPacket.packet = nopSendPacket;
522
                                currentSendPacket.data = NULL;
523
                                if(retry_mode){
524
                                        send_state = SEND_CRC;
525
                                }
526
                        }
527
 
528
                        //If the packet is an address extension, send the address extension first
529
                        if(currentSendPacket.packet->getPacketCommand() == ADDR_EXT){
530
                                dword = ((AddressExtensionPacket*)(currentSendPacket.packet))->getAddressExtension();
531
                        }
532
                        //otherwise, send the first dword
533
                        else{
534
                                dword = currentSendPacket.packet->getVector().range(31,0);
535
                        }
536
                        if(delete_command) delete cmd;
537
                        lctl = true; hctl = true;
538
                }
539
        }
540
}
541
 
542
void LogicalLayer::crcErrorDetected(){
543
        //If in retry mode, periodic CRC is not checked.  In retry mode,
544
        //pass the message up to the next layer
545
        if(!retry_mode)
546
                inter->crcErrorDetected();
547
}
548
 
549
void LogicalLayer::sendPacket(ControlPacket * packet,int * data){
550
        //Add the packet to the queue
551
        PacketAndData pad;
552
        pad.packet = packet;
553
        pad.data = data;
554
        pad.id = ++packetIdCounter;
555
        packetQueue.push_back(pad);
556
 
557
        //If in retry mode, also add it to history
558
        if(retry_mode)
559
                packetHistory.push_back(pad);
560
}
561
 
562
void LogicalLayer::flush(){
563
        //Wait (block) until all packet are sent
564
        while(!packetQueue.empty())wait();
565
}
566
 
567
int LogicalLayer::calcultatePacketCrc(ControlPacket * pkt,int * data){
568
        int crc = 0xFFFFFFFF;
569
        sc_bv<32> dword;
570
 
571
        if(pkt->getPacketCommand() == ADDR_EXT){
572
                dword = ((AddressExtensionPacket*)(currentSendPacket.packet))->getAddressExtension();
573
                calcultateDwordCrc(crc,dword,true);
574
        }
575
 
576
        dword = pkt->getVector().range(31,0);
577
        calcultateDwordCrc(crc,dword,true);
578
 
579
        if(!pkt->isDwordPacket()){
580
                dword = pkt->getVector().range(63,32);
581
                calcultateDwordCrc(crc,dword,true);
582
        }
583
 
584
        if(pkt->hasDataAssociated()){
585
                int max = (int)pkt->getDataLengthm1();
586
                for(int n = 0; n <= max; n++){
587
                        dword = data[n];
588
                        calcultateDwordCrc(crc,dword,false);
589
                }
590
        }
591
        return crc;
592
}
593
 
594
void LogicalLayer::calcultateDwordCrc(int &crc,sc_bv<32> &dword,bool ctl){
595
        for(int n = 0; n < 2; n++){
596
                int ctl_or = ctl ? 0x10000 : 0;
597
                int data = (dword.to_int() >> (n*16)) & 0xFFFF | ctl_or;
598
 
599
                for(int i = 0; i < 17; i++){
600
                        //xor highest bit w/ message
601
                        int tmp = ((crc >> 31 & 1)^((data >> i) & 1));
602
                        //substract poly if greater
603
                        crc = (tmp) ? (crc << 1) ^ PER_PACKET_CRC_POLY : ((crc << 1) | tmp);
604
                }
605
        }
606
}
607
 
608
 
609
void LogicalLayer::initiateRetrySequence(){
610
        //initiate_retry_disconnect will make the link send a disconnect nop and ignore RX
611
        initiate_retry_disconnect = true;
612
        //Go to idle RX state to be ready for a new packet when coming out of retry sequence
613
        receive_state = RECEIVE_IDLE;
614
 
615
        //Clear the current buffer count
616
        for(int n = 0; n < 3; n++){
617
                nextNodeCommandBuffersFree[n] = 0;
618
                nextNodeDataBuffersFree[n] = 0;
619
        }
620
}
621
 
622
bool LogicalLayer::isSendingNopRequired(){
623
        bool required = false;
624
        for(int n = 0; n < 3; n++){
625
                if((commandBuffersFree[n] - commandBuffersAdvertised[n]) > 2) required = true;
626
                if((dataBuffersFree[n] - dataBuffersAdvertised[n]) > 2) required = true;
627
        }
628
        return required;
629
}
630
 
631
void LogicalLayer::updateRxBufferCount(ControlPacket * receivedPacket){
632
        VirtualChannel vc = receivedPacket->getVirtualChannel();
633
        bool hasData = receivedPacket->hasDataAssociated();
634
 
635
        if(vc == VC_NONE) return;
636
        if(hasData) dataBuffersAdvertised[vc]--;
637
        else commandBuffersAdvertised[vc]--;
638
}
639
 
640
NopPacket * LogicalLayer::generateNopPacket(){
641
        sc_uint<2> responseBuffersToSend = min((commandBuffersFree[VC_RESPONSE] - commandBuffersAdvertised[VC_RESPONSE]),3);
642
        sc_uint<2> responseDataBuffersToSend = min((dataBuffersFree[VC_RESPONSE] - dataBuffersAdvertised[VC_RESPONSE]),3);
643
        sc_uint<2> postedBuffersToSend = min((commandBuffersFree[VC_POSTED] - commandBuffersAdvertised[VC_POSTED]),3);
644
        sc_uint<2> postedDataBuffersToSend = min((dataBuffersFree[VC_POSTED] - dataBuffersAdvertised[VC_POSTED]),3);
645
        sc_uint<2> npostedBuffersToSend = min((commandBuffersFree[VC_NON_POSTED] - commandBuffersAdvertised[VC_NON_POSTED]),3);
646
        sc_uint<2> npostedDataBuffersToSend = min((dataBuffersFree[VC_NON_POSTED] - dataBuffersAdvertised[VC_NON_POSTED]),3);
647
 
648
        commandBuffersAdvertised[VC_RESPONSE] += (int)responseBuffersToSend;
649
        dataBuffersAdvertised[VC_RESPONSE] += (int)responseDataBuffersToSend;
650
        commandBuffersAdvertised[VC_POSTED] += (int)postedBuffersToSend;
651
        dataBuffersAdvertised[VC_POSTED] += (int)postedDataBuffersToSend;
652
        commandBuffersAdvertised[VC_NON_POSTED] += (int)npostedBuffersToSend;
653
        dataBuffersAdvertised[VC_NON_POSTED] += (int)npostedDataBuffersToSend;
654
 
655
        return new NopPacket(responseBuffersToSend,
656
                      responseDataBuffersToSend,
657
                          postedBuffersToSend,
658
                      postedDataBuffersToSend,
659
                          npostedBuffersToSend,
660
                      npostedDataBuffersToSend,
661
                          false, false, false, rx_ack_value);
662
}
663
 

powered by: WebSVN 2.1.0

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