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

Subversion Repositories ht_tunnel

[/] [ht_tunnel/] [tags/] [START/] [bench/] [userinterface_l2/] [userinterface_tb.cpp] - Blame information for rev 2

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 acastong
//userinterface_tb.cpp
2
/* ***** BEGIN LICENSE BLOCK *****
3
 * Version: MPL 1.1
4
 *
5
 * The contents of this file are subject to the Mozilla Public License Version
6
 * 1.1 (the "License"); you may not use this file except in compliance with
7
 * the License. You may obtain a copy of the License at
8
 * http://www.mozilla.org/MPL/
9
 *
10
 * Software distributed under the License is distributed on an "AS IS" basis,
11
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12
 * for the specific language governing rights and limitations under the
13
 * License.
14
 *
15
 * The Original Code is HyperTransport Tunnel IP Core.
16
 *
17
 * The Initial Developer of the Original Code is
18
 * Ecole Polytechnique de Montreal.
19
 * Portions created by the Initial Developer are Copyright (C) 2005
20
 * the Initial Developer. All Rights Reserved.
21
 *
22
 * Contributor(s):
23
 *   Ami Castonguay <acastong@grm.polymtl.ca>
24
 *
25
 * Alternatively, the contents of this file may be used under the terms
26
 * of the Polytechnique HyperTransport Tunnel IP Core Source Code License
27
 * (the  "PHTICSCL License", see the file PHTICSCL.txt), in which case the
28
 * provisions of PHTICSCL License are applicable instead of those
29
 * above. If you wish to allow use of your version of this file only
30
 * under the terms of the PHTICSCL License and not to allow others to use
31
 * your version of this file under the MPL, indicate your decision by
32
 * deleting the provisions above and replace them with the notice and
33
 * other provisions required by the PHTICSCL License. If you do not delete
34
 * the provisions above, a recipient may use your version of this file
35
 * under either the MPL or the PHTICSCL License."
36
 *
37
 * ***** END LICENSE BLOCK ***** */
38
 
39
#include "userinterface_tb.h"
40
#include "../core/ht_datatypes.h"
41
#include "../../rtl/systemc/core_synth/synth_datatypes.h"
42
#include "../core/require.h"
43
#include <math.h>
44
 
45
using namespace std;
46
 
47
userinterface_tb::userinterface_tb(sc_module_name name): sc_module(name){
48
        std::cout << "Constructing UserInterfaceTest..." << endl;
49
 
50
        SC_THREAD(testRxInterface);
51
        sensitive_pos   <<      clk;
52
        SC_THREAD(testTxUserWrInterface);
53
        sensitive_pos   <<      clk;
54
        SC_THREAD(testTxSendSchedulerRdInterface);
55
        sensitive_pos   <<      clk;
56
 
57
        SC_THREAD(manage_memories);
58
        sensitive_pos   <<      clk;
59
 
60
        SC_METHOD(clockOutputSeparator)
61
        sensitive_neg << clk;
62
 
63
        SC_METHOD(testRxInterfaceSensitive);
64
        sensitive_pos << clk;
65
        sensitive << ui_available_usr <<
66
                ui_consume_db1 << ui_consume_db0;
67
 
68
        clockCycleNumber = 0;
69
 
70
        // Find the size of the memories
71
        // memory_size = 2^USER_MEMORY_ADDRESS_WIDTH (exponent)
72
        int memory_size = 1;
73
        for(int n = 0; n < USER_MEMORY_ADDRESS_WIDTH; n++)
74
                memory_size *= 2;
75
 
76
        //Allocate the memory
77
        memory0 = new int[memory_size];
78
        memory1 = new int[memory_size];
79
 
80
        //Initialise memory
81
        for(int n = memory_size -1; n > 0; n--){
82
                memory0[n] = 0;
83
                memory1[n] = 0;
84
        }
85
 
86
        std::cout << "Construction done..." << endl;
87
}
88
 
89
userinterface_tb::~userinterface_tb(){
90
        delete[] memory0;
91
        delete[] memory1;
92
}
93
 
94
/**
95
        Packets à envoyer :
96
        Response : TgtDone, RdResponse
97
        Request : Read, Write Posted, Write non posted, Atomic, Broadcast
98
*/
99
void userinterface_tb::testRxInterface(){
100
 
101
        //We do the general initialization of the module here.  Could be done in
102
        //any SC_THREAD actually.
103
        generalInitialisation();
104
 
105
        rxDataValue = 101;
106
 
107
        //Fill a vector of test packets
108
        //Randomly generate a series of packets
109
 
110
        for(int side = 0; side <= 1; side++){
111
                addPacketsToQueue(sendPackets[side],10);
112
        }
113
 
114
        ///Make some packets available
115
    bool ctlbuf0_availableBuffer = true;
116
        bool ctlbuf1_availableBuffer = true;
117
 
118
        if(!sendPackets[0].empty()){
119
                /** Output the packet in front of the queue
120
                        Note : an internal buffer (packetSendBuffer0) is used because I originally
121
                        thought that like VHDL, that outputs could not be read
122
                */
123
                packetSendBuffer0  = sendPackets[0].front();
124
                ro0_packet_ui = syn_ControlPacketComplete(packetSendBuffer0);
125
        }
126
        else{
127
                ctlbuf0_availableBuffer = false;
128
        }
129
 
130
        if(!sendPackets[0].empty()){
131
                packetSendBuffer1  = sendPackets[1].front();
132
                ro1_packet_ui = syn_ControlPacketComplete(packetSendBuffer1);
133
        }
134
        else{
135
                ctlbuf1_availableBuffer = false;
136
        }
137
 
138
 
139
 
140
 
141
    //Start sending test packets
142
        while(true){
143
                wait();
144
 
145
                //Don't send anything if the reset is on
146
                if(resetx.read() == false) continue;
147
 
148
                //Randomly make a packet available
149
                if(!sendPackets[0].empty())
150
                        ctlbuf0_availableBuffer = (bool)(rand() % 2);
151
                else
152
                        ctlbuf0_availableBuffer = false;
153
 
154
                //If side 0 packet is consumed
155
                if(ui_consume_ro0){
156
                        //Check that there was a packet to consume
157
                        if(!ro0_available_ui.read()){
158
                                cout << "ERROR: Packet consumed while none were available" << endl;
159
                                return;
160
                        }
161
 
162
                        //Debugging output
163
                        if(outputRdMessages){
164
                                cout << "Packet was sent from side 0 : " << packetSendBuffer0 << endl;
165
                                if(packetSendBuffer0.packet->hasDataAssociated()){
166
                                        cout << "Data length with packet : " << (int)(packetSendBuffer0.packet->getDataLengthm1() + 1) << endl;
167
                                }
168
                        }
169
 
170
                        /**
171
                                Store information about the packet that can be checked when it is sent to the
172
                                user and when data will be retrieved from the databuffer
173
                        */
174
                        sideFromWhereSendData = false;
175
                        channelToAccess = packetSendBuffer0.packet->getVirtualChannel();
176
                        dataAddress = (int)packetSendBuffer0.data_address;
177
                        dataLeftToSend = (int)(packetSendBuffer0.packet->getDataLengthm1() + 1);
178
 
179
                        //Remove current packet and output the next packet
180
                        sendPackets[0].pop_front();
181
                        if(!sendPackets[0].empty()){
182
                                packetSendBuffer0  = sendPackets[0].front();
183
                        }
184
                        else{
185
                                ctlbuf0_availableBuffer = false;
186
                        }
187
                }
188
 
189
                //Randomly make a packet available
190
                if(!sendPackets[1].empty())
191
                        ctlbuf1_availableBuffer = (bool)(rand() % 2);
192
                else
193
                        ctlbuf1_availableBuffer = false;
194
 
195
                //If side 0 packet is consumed
196
                if(ui_consume_ro1){
197
                        //Check that there was a packet to consume
198
                        if(!ro1_available_ui.read()){
199
                                cout << "ERROR: Packet consumed while none were available" << endl;
200
                                return;
201
                        }
202
 
203
                        //Debugging output
204
                        if(outputRdMessages){
205
                                cout << "Packet was sent from side 1 : " << packetSendBuffer1 << endl;
206
                                if(packetSendBuffer1.packet->hasDataAssociated()){
207
                                        cout << "Data length with packet : " << (int)(packetSendBuffer1.packet->getDataLengthm1() + 1) << endl;
208
                                }
209
                        }
210
 
211
                        /**
212
                                Store information about the packet that can be checked when it is sent to the
213
                                user and when data will be retrieved from the databuffer
214
                        */
215
                        sideFromWhereSendData = true;
216
                        channelToAccess = packetSendBuffer1.packet->getVirtualChannel();
217
                        dataAddress = (int)packetSendBuffer1.data_address;
218
                        dataLeftToSend = (int)(packetSendBuffer1.packet->getDataLengthm1() + 1);
219
 
220
 
221
                        //Remove current packet and output the next packet
222
                        sendPackets[1].pop_front();
223
                        if(!sendPackets[1].empty()){
224
                                packetSendBuffer1  = sendPackets[1].front();
225
                        }
226
                        else{
227
                                ctlbuf1_availableBuffer = false;
228
                        }
229
                }
230
 
231
                //Output the temporary buffers that were used until now
232
                ro0_available_ui = ctlbuf0_availableBuffer;
233
                ro1_available_ui = ctlbuf1_availableBuffer;
234
                ro0_packet_ui = packetSendBuffer0;
235
                ro1_packet_ui = packetSendBuffer1;
236
 
237
                //Debugging messages
238
                if(outputRdMessages && outputSide0){
239
                        cout << "ro0_available_ui = " << ctlbuf0_availableBuffer << endl;
240
                        cout << "Packet on output0 = " << packetSendBuffer0 << endl;
241
                }
242
                if(outputRdMessages && outputSide1){
243
                        cout << "ro1_available_ui = " << ctlbuf1_availableBuffer << endl;
244
                        cout << "Packet on output1 = " << packetSendBuffer1 << endl;
245
                }
246
 
247
        }
248
 
249
}
250
 
251
void userinterface_tb::testRxInterfaceSensitive(){
252
        /** This is a very poor test...  The validity of the data
253
                received is not even checked automatically...  Some work
254
                would be needed to make this a completely autonomous test, but
255
                at least the framework is there.
256
        */
257
 
258
        //Consume data for user where there is some available
259
        if(ui_available_usr.read() || dataLeftToSend > 0){
260
                if(clk.event() && outputRdMessages){
261
                        cout << "User received data : " << ui_packet_usr.read() << endl;
262
                }
263
                usr_consume_ui = true;
264
        }
265
        else
266
                usr_consume_ui = false;
267
 
268
        //
269
        if(ui_consume_db1.read()){
270
                if(clk.event() && resetx.read() == true){
271
                        /*
272
                        require(dataLeftToSend > 0,"No more data to send!");
273
                        require(sideFromWhereSendData == true,"Reading from wrong side!");
274
                        require(channelToAccess == ui_vctype_db1.read(),"Reading from wrong vc! side");
275
                        require(dataAddress == ui_address_db1.read(),"Reading from wrong address!");
276
                        */
277
 
278
                        dataLeftToSend--;
279
                        rxDataValue ++;
280
                        if(outputRdMessages){
281
                                cout << "Just sent data side 1 : " << rxDataValue << endl;
282
                                cout << "VC being accessed : " << ui_vctype_db1.read() << endl;
283
                        }
284
 
285
                }
286
 
287
                db1_data_ui = sc_uint<32>(rxDataValue);
288
                if(outputRdMessages){
289
                        cout << "Data left to send : " << dataLeftToSend << endl;
290
                }
291
        }
292
        else if(ui_consume_db0.read()){
293
                if(clk.event() && resetx.read() == true){
294
                        /*
295
                        require(dataLeftToSend > 0,"No more data to send!");
296
                        require(sideFromWhereSendData == false,"Reading from wrong side!");
297
                        require(channelToAccess == ui_vctype_db0.read(),"Reading from wrong vc!");
298
                        require(dataAddress == ui_address_db0.read(),"Reading from wrong address!");
299
                        */
300
 
301
                        dataLeftToSend--;
302
                        rxDataValue++;
303
                        if(outputRdMessages){
304
                                cout << "Just sent data side 0 : " << rxDataValue << endl;
305
                                cout << "VC being accessed : " << ui_vctype_db0.read() << endl;
306
                        }
307
                }
308
 
309
                db0_data_ui = sc_uint<32>(rxDataValue);
310
 
311
                if(outputRdMessages){
312
                        cout << "Data left to send : " << dataLeftToSend << endl;
313
                }
314
        }
315
 
316
}
317
 
318
 
319
void userinterface_tb::testTxUserWrInterface(){
320
 
321
        int dataValue = 202;
322
 
323
        usr_packet_ui = sc_bv<64>();
324
        usr_available_ui = false;
325
        usr_side_ui = false;
326
 
327
        addPacketsToQueue(userPacketQueue,50,9999999);
328
 
329
        PacketContainer usr_packetBuffer ;
330
 
331
        int dataLengthToSend = (int)usr_packetBuffer->getDataLengthm1();
332
 
333
        bool done = false;
334
 
335
        while(!done){
336
                wait();
337
 
338
                //Wait for reset to be done
339
                if(resetx.read() == false) continue;
340
 
341
                //If a packet is being sent
342
                if(usr_available_ui.read() ){
343
                        if(outputTxMessages){
344
                                cout << "Packet was sent : " << usr_packetBuffer << endl;
345
                        }
346
                        //If data associated with the packet, send it
347
                        if(usr_packetBuffer->hasDataAssociated()){
348
                                if(outputTxMessages){
349
                                        cout << "Sending data : " << dataValue << endl;
350
                                }
351
                                dataLengthToSend = (int)usr_packetBuffer->getDataLengthm1();
352
                                cout << "Sent : " << sc_uint<64>(dataValue) << endl;
353
                                usr_packet_ui = sc_uint<64>(dataValue++);
354
                                usr_available_ui = false;
355
                        }
356
                        //Otherwise, if there are packets left in the queue, send them
357
                        else if(!userPacketQueue.empty()){
358
                                usr_packetBuffer = userPacketQueue.front();
359
                                usr_packet_ui = usr_packetBuffer;
360
                                userPacketQueue.pop_front();
361
                                usr_available_ui = true;
362
                        }
363
                        //If no packets left, we're done
364
                        else{
365
                                usr_available_ui = false;
366
                                done = true;
367
                        }
368
                }
369
                //Si il reste des données à envoyer, on envoie ces données
370
                else if(dataLengthToSend > 0){
371
                        if(outputTxMessages){
372
                                cout << "Sending data : " << dataValue << endl;
373
                        }
374
                        dataLengthToSend-- ;
375
                        usr_packet_ui = sc_uint<64>(dataValue++);
376
                        usr_available_ui = false;
377
                }
378
                //No more data to send, output next message if any left to send
379
                else{
380
                        if(outputTxMessages){
381
                                cout << "Finished sending data, putting new packet on line" << endl;
382
                        }
383
                        if(!userPacketQueue.empty()){
384
                                usr_packetBuffer = userPacketQueue.front();
385
                                userPacketQueue.pop_front();
386
                                usr_packet_ui = usr_packetBuffer;
387
                                usr_available_ui = true;
388
                        }
389
                        else{
390
                                usr_available_ui = false;
391
                                done = true;
392
                        }
393
 
394
                }
395
        }
396
        usr_available_ui = false;
397
}
398
 
399
void userinterface_tb::testTxSendSchedulerRdInterface(){
400
 
401
        //Initialize flow control interface to an initial value
402
        fc0_datavc_ui = VC_POSTED;
403
        fc0_consume_data_ui = false;
404
        fc0_user_fifo_ge2_ui = sc_bv<3>();
405
 
406
        fc1_datavc_ui = VC_POSTED;
407
        fc1_consume_data_ui = false;
408
        fc1_user_fifo_ge2_ui = sc_bv<3>();
409
 
410
        //Represents the USER fifo : [side][VC]
411
        std::deque<PacketContainer> packetQueue[2][3];
412
        int dataLeftToReceive[2] = {0,0};
413
        VirtualChannel dataToReceiveFromVc[2];
414
 
415
        while(true){
416
                wait();
417
 
418
                //Wait for reset to be over
419
                if(resetx.read() == false) continue;
420
 
421
                //Set some default values
422
                fc0_datavc_ui = VC_POSTED;
423
                fc0_consume_data_ui = false;
424
                fc1_datavc_ui = VC_POSTED;
425
                fc1_consume_data_ui = false;
426
 
427
                /**
428
                        The following two lines are to force to NEVER read
429
                        the data of the user interface to test the buffers
430
                        filling up.
431
                */
432
                //dataLeftToReceive[0] = 0;
433
                //dataLeftToReceive[1] = 0;
434
 
435
                //****************************************************************
436
                //Read data if any left to read, or
437
                //maybe read from the FIFO
438
                //*****************************************************************
439
                if(dataLeftToReceive[0] > 0){
440
                        if(rand() % 10){
441
                                //Randomly read data 90% of the time
442
                                fc0_consume_data_ui = true;
443
                                fc0_datavc_ui = dataToReceiveFromVc[0];
444
                                dataLeftToReceive[0]--;
445
                                if(outputTxMessages){
446
                                        cout << "Reading data from 0 : " << (sc_uint<32>) ui_data_fc0 << " left = " << dataLeftToReceive[0] << endl;
447
                                }
448
                        }
449
                }
450
                //If there are data received from FIFO
451
                else if(!packetQueue[0][0].empty() ||
452
                            !packetQueue[0][1].empty() ||
453
                                !packetQueue[0][2].empty()){
454
                        if(rand() % 4){
455
                                //Select vc to read from
456
                                VirtualChannel vc;
457
                                if(!packetQueue[0][VC_RESPONSE].empty()) vc = VC_RESPONSE;
458
                                else if(!packetQueue[0][VC_POSTED].empty()) vc = VC_POSTED;
459
                                else vc = VC_NON_POSTED;
460
 
461
                                //Get the packet
462
                                PacketContainer &packet = packetQueue[0][vc].front();
463
                                //and find how much data it has
464
                                if(packet->hasDataAssociated()){
465
                                        dataLeftToReceive[0] = (int)(packet->getDataLengthm1() + 1);
466
                                        dataToReceiveFromVc[0] = packet->getVirtualChannel();
467
                                }
468
                                if(outputTxMessages){
469
                                        cout << "Reading packet from fifo0 "  << endl <<
470
                                                packet << endl;
471
                                }
472
                                //Remove packet from queue (virtual user fifo)
473
                                packetQueue[0][vc].pop_front();
474
                        }
475
                };
476
 
477
                if(dataLeftToReceive[1] > 0){
478
                        if(rand() % 10){
479
                                //Randomly read data 90% of the time
480
                                fc1_consume_data_ui = true;
481
                                fc1_datavc_ui = dataToReceiveFromVc[1];
482
                                dataLeftToReceive[1]--;
483
                                if(outputTxMessages){
484
                                        cout << "Reading data from 1 " << endl;
485
                                }
486
                        }
487
                }
488
                else if(!packetQueue[1][0].empty() ||
489
                            !packetQueue[1][1].empty() ||
490
                                !packetQueue[1][2].empty()){
491
                        if(rand() % 4){
492
                                //Select vc to read from
493
                                VirtualChannel vc;
494
                                if(!packetQueue[1][VC_RESPONSE].empty()) vc = VC_RESPONSE;
495
                                else if(!packetQueue[1][VC_POSTED].empty()) vc = VC_POSTED;
496
                                else vc = VC_NON_POSTED;
497
 
498
                                //Get the packet
499
                                PacketContainer &packet = packetQueue[1][vc].front();
500
                                //and find how much data it has
501
                                if(packet->hasDataAssociated()){
502
                                        dataLeftToReceive[1] = (int)(packet->getDataLengthm1() + 1);
503
                                        dataToReceiveFromVc[1] = (int)packet->getVirtualChannel();
504
                                }
505
                                if(outputTxMessages){
506
                                        cout << "Reading packet from fifo1 "  << endl <<
507
                                                packet << endl;
508
                                }
509
                                //Remove packet from queue (virtual user fifo)
510
                                packetQueue[1][vc].pop_front();
511
                        }
512
                };
513
 
514
                //****************************************************************
515
                //Add the received packet to the FIFO
516
                //Check if the received packet is valid
517
                //*****************************************************************
518
                if(ui_available_fc0.read()){
519
                        PacketContainer ui_packet_fc0_sim = ControlPacket::createPacketFromQuadWord(ui_packet_fc0.read());
520
                        VirtualChannel vc = ui_packet_fc0_sim->getVirtualChannel();
521
                        bool hasData = ui_packet_fc0_sim->hasDataAssociated();
522
 
523
                        require(vc < 4,"Invalid virtual channel packet received from 0\n");
524
 
525
                        require(packetQueue[0][vc].size() <= USER_FIFO_DEPTH,
526
                                        "ERROR: trying to write in a full FIFO!\n");
527
 
528
                        packetQueue[0][vc].push_back(ui_packet_fc0_sim);
529
                        if(outputTxMessages){
530
                                cout << "Adding Packet to fifo0" << endl
531
                                        << ui_packet_fc0.read() << endl;
532
                        }
533
                }
534
 
535
                if(ui_available_fc1.read()){
536
                        PacketContainer ui_packet_fc1_sim = ControlPacket::createPacketFromQuadWord(ui_packet_fc1.read());
537
                        VirtualChannel vc = ui_packet_fc1_sim->getVirtualChannel();
538
                        bool hasData = ui_packet_fc1_sim->hasDataAssociated();
539
 
540
                        require(vc < 4,"Invalid virtual channel packet received from 1\n");
541
 
542
                        require(packetQueue[1][vc].size() <= USER_FIFO_DEPTH,
543
                                        "ERROR: trying to write in a full FIFO!\n");
544
 
545
                        packetQueue[1][vc].push_back(ui_packet_fc1_sim);
546
                        if(outputTxMessages){
547
                                cout << "Adding Packet to queue1" << endl
548
                                        << ui_packet_fc1.read() << endl;
549
                        }
550
                }
551
 
552
                //****************************************************************
553
                //Calculate the FreeVC signal to send to the user interface
554
                //*****************************************************************
555
                sc_bv<3> send0_ge2_buf;
556
                for(int n = 0; n < 3 ; n++){
557
                        send0_ge2_buf[n] = packetQueue[0][n].size() >= 2;
558
                }
559
                fc0_user_fifo_ge2_ui = send0_ge2_buf;
560
 
561
                sc_bv<3> send1_ge2_buf;
562
                for(int n = 0; n < 3 ; n++){
563
                        send1_ge2_buf[n] = packetQueue[1][n].size() >= 2;
564
                }
565
                fc1_user_fifo_ge2_ui = send1_ge2_buf;
566
        }
567
 
568
}
569
 
570
void userinterface_tb::generalInitialisation(){
571
        ControlPacket::outputExtraInformation = true;
572
        csr_default_dir = true;
573
        csr_masterhost = false;
574
        dataLeftToSend = 0;
575
        maxDataAddress = (int)pow(2,BUFFERS_ADDRESS_WIDTH);
576
 
577
        for(int n = 0 ; n < DirectRoute_NumberDirectRouteSpaces;n++){
578
                csr_direct_route_oppposite_dir[n] = false;
579
                csr_direct_route_base[n] = sc_bv<32>();
580
                csr_direct_route_limit[n] = sc_bv<32>();
581
        }
582
        csr_direct_route_oppposite_dir[0] = true;
583
        csr_direct_route_base[0] = sc_bv<32>("0x12950468");
584
        csr_direct_route_limit[0] = sc_bv<32>("0x16359203");
585
}
586
 
587
void userinterface_tb::addPacketsToQueue(
588
        std::deque<PacketContainer> &queue,int number,int seed){
589
 
590
        //Randomly generate chains, this is the number of packets that are
591
        //part of the chain left to generate
592
        int chainLengthLeft = 0;
593
        //Temp variable to store generate packets
594
        PacketContainer pkt;
595
        //Seed the random generator
596
        if(seed > 0){
597
                srand(seed);
598
        }
599
 
600
        //If adding packets to queue, verify if the last packet was part of the
601
        //chain and add a last packet for that chani
602
        if(!queue.empty()){
603
                pkt = queue.back();
604
                if(pkt->isChain()){
605
                        chainLengthLeft = 1;
606
                }
607
        }
608
 
609
        //Add packets to the queue
610
        for(int n = 0; n < number;n++){
611
                getRandomPacket(pkt,chainLengthLeft);
612
                queue.push_back(pkt);
613
        }
614
}
615
 
616
void userinterface_tb::addPacketsToQueue(
617
                std::deque<ControlPacketComplete> &queue,int number,int seed){
618
 
619
        //Randomly generate chains, this is the number of packets that are
620
        //part of the chain left to generate
621
        int chainLengthLeft = 0;
622
        //Temp variable to store generate packets
623
        ControlPacketComplete pkt;
624
        sc_uint<BUFFERS_ADDRESS_WIDTH> randomDataAddress = rand() % maxDataAddress;
625
 
626
        //Seed the random generator
627
        if(seed > 0){
628
                srand(seed);
629
        }
630
 
631
        //If adding packets to queue, verify if the last packet was part of the
632
        //chain and add a last packet for that chani
633
        if(!queue.empty()){
634
                pkt = queue.back();
635
                if(pkt.packet->isChain()){
636
                        chainLengthLeft = 1;
637
                }
638
        }
639
 
640
        //Add packets to the queue
641
        for(int n = 0; n < number;n++){
642
                getRandomPacket(pkt.packet,chainLengthLeft);
643
 
644
                pkt.data_address = randomDataAddress;
645
                queue.push_back(pkt);
646
        }
647
}
648
 
649
void userinterface_tb::getRandomPacket(PacketContainer &lastPacketToUpdateWithNew,
650
                                                                                                   int &chainLengthLeft){
651
        /** Generate random elements to create random packets
652
        */
653
        int randomPacketValue = rand() % 7;
654
        sc_bv<4> randomDataLength = sc_uint<4>(rand() % 16);
655
        sc_bv<4> randomSeqID = sc_uint<4>(rand() % 16);
656
        sc_bv<5> randomUnitID = sc_uint<5>(rand() % 32);
657
        sc_bv<2> randomRqUID = sc_uint<2>(rand() % 4);
658
        sc_bv<5> randomSrcTag = sc_uint<5>(rand() % 32);
659
        bool randomBridge = rand() % 2;
660
        bool randomPassPW = rand() % 2;
661
        bool randomResponsePassPW = rand() % 2;
662
        bool randomDoubleWordDataLength = rand() % 2;
663
        bool randomDataError = rand() % 2;
664
 
665
        sc_bv<40> randomAddress;
666
        for(int j = 0; j < 40; j++){
667
                bool randomBool = rand() % 2;
668
                randomAddress[j] = randomBool;
669
        }
670
        bool randomStartChain = !(rand() % 10);
671
 
672
        //If part of chain
673
        if(chainLengthLeft > 0){
674
                //The last packet of a chain of packets does not have the chain bit active
675
                bool chainBitOn = chainLengthLeft != 1;
676
                chainLengthLeft--;
677
 
678
                //Create a new Posted write which is to the same destination using the last packet valeus
679
                //and some new random values
680
                WritePacket* oldPacket = dynamic_cast<WritePacket*>(lastPacketToUpdateWithNew.getPacketRef());
681
                ControlPacket* newPacket = new WritePacket(
682
                        oldPacket->getSeqID(),
683
                        oldPacket->getUnitID(),
684
                        randomDoubleWordDataLength,
685
                        randomAddress.range(39,2),
686
                        randomDoubleWordDataLength,
687
                        oldPacket->getPassPW(),
688
                        oldPacket->getDataError(),
689
                        chainBitOn);
690
                lastPacketToUpdateWithNew.takeControl(newPacket);
691
 
692
        }
693
        //If starting a new chain
694
        else if(randomStartChain){
695
                //Generate a random chain length (1 to 7)
696
                chainLengthLeft = rand() % 7+1;
697
 
698
                //Create a random posted write packet with chain bit on
699
                lastPacketToUpdateWithNew.takeControl(
700
                        new WritePacket( randomSeqID,
701
                        randomUnitID,
702
                        randomDoubleWordDataLength,
703
                        randomAddress.range(39,2),
704
                        randomDoubleWordDataLength,
705
                        randomPassPW,
706
                        randomDataError,
707
                        true) ); //Est de type Chain
708
 
709
        }
710
        else{
711
                //Otherwise, create a completely new random packet
712
                switch(randomPacketValue) {
713
                case 0 :
714
                        lastPacketToUpdateWithNew.takeControl(
715
                                new TargetDonePacket(randomUnitID,
716
                                randomSrcTag,
717
                                randomRqUID,
718
                                randomBridge,
719
                                RE_NORMAL,
720
                                randomPassPW));
721
                        break;
722
 
723
                case 1 :
724
                        lastPacketToUpdateWithNew.takeControl(
725
                                new ReadResponsePacket(randomUnitID,
726
                                randomSrcTag,
727
                                randomRqUID,
728
                                randomDataLength,
729
                                randomBridge,
730
                                RE_NORMAL,
731
                                randomPassPW));
732
                        break;
733
 
734
                case 2 :
735
                        lastPacketToUpdateWithNew.takeControl(
736
                                new ReadPacket(randomSeqID,
737
                                randomUnitID,
738
                                randomSrcTag,
739
                                randomDataLength,
740
                                randomAddress.range(39,2),
741
                                randomDoubleWordDataLength,
742
                                randomPassPW,
743
                                randomResponsePassPW)) ;
744
 
745
                        break;
746
 
747
                case 3 :
748
                        lastPacketToUpdateWithNew.takeControl(
749
                                new WritePacket( randomSeqID,
750
                                randomUnitID,
751
                                randomDataLength,
752
                                randomAddress.range(39,2),
753
                                randomDoubleWordDataLength,
754
                                randomPassPW,
755
                                randomDataError,
756
                                false)) ; //Pas de type Chain
757
                        break;
758
                case 4 :
759
                        lastPacketToUpdateWithNew.takeControl(
760
                                new WritePacket(  randomSeqID,
761
                                randomUnitID,
762
                                randomSrcTag,
763
                                randomDataLength,
764
                                randomAddress.range(39,2),
765
                                randomDoubleWordDataLength,
766
                                randomPassPW));
767
 
768
                        break;
769
                case 5 :
770
                        lastPacketToUpdateWithNew.takeControl(
771
                                new AtomicPacket( randomSeqID,
772
                                randomUnitID,
773
                                randomSrcTag,
774
                                randomDataLength,
775
                                randomAddress.range(39,2),
776
                                randomPassPW));
777
 
778
                        break;
779
 
780
                case 6 :
781
                        lastPacketToUpdateWithNew.takeControl(new BroadcastPacket(
782
                                randomSeqID,
783
                                randomUnitID,
784
                                randomPassPW,
785
                                randomAddress.range(39,2)
786
                                ));
787
                }
788
        }
789
 
790
}
791
 
792
void userinterface_tb::manage_memories(){
793
 
794
        while(true){
795
                wait();
796
                //Manage writing
797
                if(ui_memory_write0.read()){
798
                        memory0[(sc_uint<7>)ui_memory_write_address.read()] = (int)(sc_uint<32>)(ui_memory_write_data.read());
799
                }
800
                if(ui_memory_write1.read()){
801
                        memory1[(sc_uint<7>)ui_memory_write_address.read()] = (int)(sc_uint<32>)(ui_memory_write_data.read());
802
                }
803
 
804
                //Manage reading
805
                ui_memory_read_data0 = memory0[(sc_uint<7>)ui_memory_read_address0.read()];
806
                ui_memory_read_data1 = memory1[(sc_uint<7>)ui_memory_read_address1.read()];
807
 
808
        }
809
}

powered by: WebSVN 2.1.0

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