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

Subversion Repositories ht_tunnel

[/] [ht_tunnel/] [trunk/] [bench/] [reordering_l2/] [reordering_l2_tb.cpp] - Blame information for rev 19

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 acastong
//reordering_l2_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 "reordering_l2_tb.h"
40
 
41
using namespace std;
42
 
43
reordering_l2_tb::reordering_l2_tb(sc_module_name name){
44
        SC_THREAD(simulate);
45
        sensitive_pos(clk);
46
 
47
        SC_METHOD(consume_data);
48
        sensitive << ro_available_csr << ro_available_ui << ro_available_fwd;
49
        sensitive << read_csr << read_fwd << read_ui;
50
 
51
        SC_METHOD(manage_memories);
52
        sensitive_pos << clk;
53
 
54
        srand(7941);
55
 
56
}
57
 
58
void reordering_l2_tb::simulate(){
59
        //Start with a reset
60
        resetx = false;
61
 
62
        //Randomly set par addresses
63
        sc_uint<40> tmp_40b[NbRegsBars];
64
        for(int n = 0; n < NbRegsBars; n++){
65
                //Generate a random 40-bit vector
66
                tmp_40b[n].range(14,0) = sc_uint<32>(rand()).range(14,0);
67
                tmp_40b[n].range(29,15) = sc_uint<32>(rand()).range(14,0);
68
                tmp_40b[n].range(39,30) = sc_uint<32>(rand()).range(9,0);
69
        }
70
 
71
        //Lower part of bar is zero, set the random part to zero
72
        tmp_40b[0].range(Header_BarSlotHarwireSize0_m1,0) = 0;
73
        if(NbRegsBars > 0) tmp_40b[1].range(Header_BarSlotHarwireSize1_m1,0) = 0;
74
        if(NbRegsBars > 1) tmp_40b[2].range(Header_BarSlotHarwireSize2_m1,0) = 0;
75
        if(NbRegsBars > 2) tmp_40b[3].range(Header_BarSlotHarwireSize3_m1,0) = 0;
76
        if(NbRegsBars > 3) tmp_40b[4].range(Header_BarSlotHarwireSize4_m1,0) = 0;
77
        if(NbRegsBars > 4) tmp_40b[5].range(Header_BarSlotHarwireSize5_m1,0) = 0;
78
 
79
        for(int n = 0; n < NbRegsBars; n++){
80
                //Set the bar address
81
                csr_bar[n] = tmp_40b[n];
82
        }
83
        //Choose a random unitID for this node
84
        csr_unit_id = (sc_uint<5>)sc_uint<32>(rand()).range(4,0);
85
 
86
        //////////////////////////////////////////////
87
        // Set some initial values
88
        //////////////////////////////////////////////  
89
 
90
        csr_ack_ro = false;
91
        ui_ack_ro = false;
92
        fwd_ack_ro = false;
93
        eh_ack_ro = false;
94
 
95
        fc_nop_sent = true;
96
 
97
        cd_available_ro = false;
98
 
99
        cd_data_pending_ro = false;
100
 
101
        csr_memory_space_enable = true;
102
        csr_io_space_enable = true;
103
 
104
        csr_direct_route_enable = true;
105
        csr_sync = false;
106
 
107
        //csr_clumping_configuration = "00000000111000000000000000000000";
108
        /**ID's 20 to 23 are clumped together*/
109
        for(int n = 0; n < 32; n++)
110
                clumped_unit_id[n] = n;
111
        clumped_unit_id[21] = 20;
112
        clumped_unit_id[22] = 20;
113
        clumped_unit_id[23] = 20;
114
 
115
    //The unitID's that have directRoute enabled
116
        csr_direct_route_enable =    "00000000000000000000000000000000";
117
 
118
#ifdef ENABLE_REORDERING
119
        csr_unitid_reorder_disable = false;
120
#endif
121
        fwd_next_node_buffer_status_ro = "111111";
122
 
123
 
124
#ifdef RETRY_MODE_ENABLED
125
        lk_rx_connected = true;
126
        csr_retry = false;
127
#endif
128
 
129
        //Hold reset for a some cycles
130
        for(int n = 0; n < 3; n++)
131
                wait();
132
 
133
        //Stop reset
134
        resetx = true;
135
 
136
        //A temporary packet variable to reuse
137
        ReorderTBPacket tb_pkt;
138
 
139
        /////////////////////////////////////////
140
        // Send Misc packets, no reordering
141
        // Test one VC at the time
142
        // This tests the proper operation of the entrance reordering
143
        // dans the buffers when not being reordered
144
        /////////////////////////////////////////
145
        fc_nop_sent = true;
146
        cd_data_pending_ro = false;
147
        cout << "Begin test: Send Misc packets, no reordering" << endl;
148
 
149
        for(int vc = 0; vc < 3; vc++){
150
                cout << "Begin test for vc: " << vc << endl;
151
 
152
                int packet_to_send = 25;
153
                int packets_received = 0;
154
 
155
                int idle_counter = 0;
156
 
157
                while(packets_received != 25){
158
 
159
                        ////////////////////////////////////////////
160
                        // Read reordering output
161
                        ////////////////////////////////////////////
162
 
163
                        //Make sure we don't fall in an infinite loop
164
                        if(!ro_available_csr.read() &&
165
                                !ro_available_ui.read() &&
166
                                !ro_available_fwd.read() &&
167
                                !packet_sent.empty())
168
                        {
169
                                idle_counter++;
170
                                if(idle_counter > 10){
171
                                        cout << "ERROR: No packets are being received!" << endl;
172
                                        return;
173
                                }
174
                        }
175
                        else{
176
                                idle_counter = 0;
177
                        }
178
 
179
                        //80% chance of reading from the many destination
180
                        read_csr = (rand() % 10) < 8;
181
                        read_fwd = (rand() % 10) < 8;
182
                        read_ui = (rand() % 10) < 8;
183
 
184
                        //Find the first packet in the list of packets 
185
                        //Start by creating an iterator
186
                        deque<ReorderTBPacket>::iterator first_accepted = packet_sent.begin();
187
                        bool found_accepted = false;
188
                        //loop over all elements until an accepted is found
189
                        while(first_accepted != packet_sent.end()){
190
                                if(first_accepted->accepted){
191
                                        found_accepted = true;
192
                                        break;
193
                                }
194
                                first_accepted++;
195
                        }
196
 
197
                        //Accepted packet can only be sent to one destination, CSR or UI
198
                        if(ui_ack_ro.read() && csr_ack_ro.read()){
199
                                cout << "ERROR: Packets sent to UI and CSR simulaneoulsy" << endl;
200
                                return;
201
                        }
202
 
203
                        //If CSR acks a packet
204
                        if(csr_ack_ro.read()){
205
                                //Check if there is a packet to send
206
                                if(packet_sent.size() == 0 || !found_accepted){
207
                                        cout << "ERROR: Packet available when none in buffers..." << endl;
208
                                        return;
209
                                }
210
                                //If not the correct packet, display an error 
211
                                if(ro_packet_csr.read().packet != first_accepted->pkt.packet
212
                                        || ! first_accepted->csr)
213
                                {
214
                                        cout << "ERROR: Packet sent to CSR by error" << endl;
215
                                        return;
216
                                }
217
                                //If correct, remove from queue
218
                                else{
219
                                        packet_sent.erase(first_accepted);
220
                                        packets_received++;
221
                                }
222
 
223
                        }
224
                        //If UI acks 
225
                        if(ui_ack_ro.read()){
226
                                //Check if there was a packet to sent
227
                                if(packet_sent.size() == 0 || !found_accepted){
228
                                        cout << "ERROR: Packet available when none in buffers..." << endl;
229
                                        return;
230
                                }
231
                                //If not the correct packet, display an error 
232
                                if(ro_packet_ui.read().packet != first_accepted->pkt.packet
233
                                        || first_accepted->csr)
234
                                {
235
                                        cout << "ERROR: Packet sent to UI by error, " <<
236
                                                ro_packet_ui.read().packet.to_string(SC_HEX) << endl;
237
                                        cout << "   expected: " <<
238
                                                first_accepted->pkt.packet.to_string(SC_HEX) << endl;
239
                                        resetx = false;
240
                                        return;
241
                                }
242
                                else{
243
                                        //If the packet must also go to forward (like for a broadcast), just
244
                                        //erase the fact that it must go to accepted
245
                                        if(first_accepted->forward) first_accepted->accepted = false;
246
                                        //Otherwise, erase the packet
247
                                        else{
248
                                                packet_sent.erase(first_accepted);
249
                                                packets_received++;
250
                                        }
251
 
252
                                }
253
                        }
254
 
255
                        //Find the first packet for the forward destination in the list of packet sent
256
                        deque<ReorderTBPacket>::iterator first_forward = packet_sent.begin();;
257
                        bool found_forward = false;
258
                        while(first_forward != packet_sent.end()){
259
                                if(first_forward->forward){
260
                                        found_forward = true;
261
                                        break;
262
                                }
263
                                first_forward++;
264
                        }
265
 
266
 
267
                        //If packet is acked
268
                        if(fwd_ack_ro.read()){
269
                                //Check that there is a packet to ack
270
                                if(packet_sent.size() == 0 || !found_forward){
271
                                        cout << "ERROR: Packet available when none in buffers..." << endl;
272
                                        return;
273
                                }
274
                                //If it is not the correct packet, display error
275
                                if(ro_packet_fwd.read().packet != first_forward->pkt.packet)
276
                                {
277
                                        cout << "ERROR: Packet sent to FWD by error, " <<
278
                                                ro_packet_fwd.read().packet.to_string(SC_HEX) <<
279
                                                " expected: " << first_forward->pkt.packet.to_string(SC_HEX) << endl;
280
                                        return;
281
                                }
282
                                else{
283
                                        //If the packet must also go to accepted (like for a broadcast), just
284
                                        //erase the fact that it must go to forward
285
                                        if(first_forward->accepted) first_forward->forward = false;
286
                                        //Otherwise, erase the packet
287
                                        else{
288
                                                packet_sent.erase(first_forward);
289
                                                packets_received++;
290
                                        }
291
                                }
292
 
293
                        }
294
 
295
                        ////////////////////////////////////////////
296
                        // Send packets
297
                        ////////////////////////////////////////////
298
 
299
                        //80% chance of sending packet
300
                        bool send = (rand() % 10) < 8;
301
 
302
                        //If there is room in buffers, we still have packet to send (from the initial
303
                        //number that was set and we want to send
304
                        if(packet_sent.size() < NB_OF_BUFFERS && packet_to_send > 0 && send){
305
                                if(vc == VC_POSTED){
306
                                        generate_random_posted_pkt(tb_pkt,POSTED_ANY);
307
                                        //Make sure  passpw = false
308
                                        tb_pkt.pkt.packet[15] = false;
309
                                }
310
                                else if(vc == VC_NON_POSTED){
311
                                        generate_random_nposted_pkt(tb_pkt,NPOSTED_ANY);
312
                                        //Make sure  passpw = false
313
                                        tb_pkt.pkt.packet[15] = false;
314
                                }
315
                                else{
316
                                        generate_random_response_pkt(tb_pkt,RESPONSE_ANY);
317
                                        //Make sure  passpw = false
318
                                        tb_pkt.pkt.packet[15] = false;
319
                                }
320
 
321
                                cd_available_ro = true;
322
                                cd_packet_ro = tb_pkt.pkt;
323
                                packet_to_send--;
324
                                packet_sent.push_back(tb_pkt);
325
                        }
326
                        else{
327
                                cd_available_ro = false;
328
                        }
329
                        wait();
330
                }
331
                cout << "Test done for vc: " << vc << endl;
332
        }
333
 
334
        cout << "Test successful" << endl << endl;
335
 
336
        /////////////////////////////////////////
337
        // Send Misc packets, reordering
338
        /////////////////////////////////////////
339
 
340
        /**
341
                The previous tests sent completely random packets and checked
342
                that they were still in order and correct.  For the reordering,
343
                it is not so easy, so this sends a series of pre-defined
344
                vectors and makes sure they are received in the also pre-defined
345
                correct order.
346
 
347
                Only send packets for the forward destination to simplify tests.
348
        */
349
 
350
        wait();
351
 
352
        cout << "Begin packet reordering test"<< endl;
353
 
354
        read_csr = false;
355
        read_fwd = false;
356
        read_ui = false;
357
 
358
        //There are 4 tests to make
359
        deque<ReorderTBPacket> to_send[4];
360
        deque<ReorderTBPacket> to_receive[4];
361
 
362
        //Test 1 & 2 - passPW and sequence for posted and non-posted
363
        //Create a bunch of packets alternating passPW = true and false
364
        tb_pkt.pkt.isPartOfChain = false;
365
        tb_pkt.pkt.data_address = sc_uint<32>(rand()).range(BUFFERS_ADDRESS_WIDTH-1,0);
366
        tb_pkt.accepted = false;
367
        tb_pkt.forward = true;
368
        tb_pkt.pkt.error64BitExtension = false;
369
 
370
        for(int n = 0; n < 8; n++){
371
                generate_random_forward_posted_pkt(tb_pkt.pkt.packet,false);
372
                tb_pkt.pkt.packet[15] = n % 2 || n == 0;
373
                to_send[0].push_back(tb_pkt);
374
                generate_random_forward_nposted_pkt(tb_pkt.pkt.packet);
375
                tb_pkt.pkt.packet[15] = n % 2 || n == 0;
376
                to_send[1].push_back(tb_pkt);
377
        }
378
 
379
        //Insert a sequence in the packets, also testing unitID clumping
380
        for(int n = 3; n < 6; n++){
381
                to_send[0][n].pkt.packet.range(7,6) = "01";
382
                to_send[0][n].pkt.packet.range(14,10) = "10101";
383
                //Different unitID, but same clumped UnitID
384
                to_send[0][n].pkt.packet.range(9,8) = sc_uint<2>(n-3);
385
                to_send[1][n].pkt.packet.range(7,6) = "01";
386
                to_send[1][n].pkt.packet.range(14,10) = "10101";
387
                //Different unitID, but same clumped UnitID
388
                to_send[1][n].pkt.packet.range(9,8) = sc_uint<2>(n-3);
389
        }
390
 
391
        //Generate the order which the packet should be received
392
        to_receive[0].push_back(to_send[0][0]);
393
        to_receive[1].push_back(to_send[1][0]);
394
        to_receive[0].push_back(to_send[0][1]);
395
        to_receive[1].push_back(to_send[1][1]);
396
        to_receive[0].push_back(to_send[0][3]);
397
        to_receive[1].push_back(to_send[1][3]);
398
        to_receive[0].push_back(to_send[0][2]);
399
        to_receive[1].push_back(to_send[1][2]);
400
        to_receive[0].push_back(to_send[0][4]);
401
        to_receive[1].push_back(to_send[1][4]);
402
        to_receive[0].push_back(to_send[0][5]);
403
        to_receive[1].push_back(to_send[1][5]);
404
        to_receive[0].push_back(to_send[0][7]);
405
        to_receive[1].push_back(to_send[1][7]);
406
        to_receive[0].push_back(to_send[0][6]);
407
        to_receive[1].push_back(to_send[1][6]);
408
 
409
        //Test 3 - posted chains
410
        //Create a bunch of packets alternating passPW = true and false
411
        for(int n = 0; n < 8; n++){
412
                generate_random_forward_posted_pkt(tb_pkt.pkt.packet,n == 4 || n==5);
413
                tb_pkt.pkt.packet[15] = n % 2 || n == 0;
414
                to_send[2].push_back(tb_pkt);
415
        }
416
 
417
        //Generate the order which the packet should be received
418
        to_receive[2].push_back(to_send[2][0]);
419
        to_receive[2].push_back(to_send[2][1]);
420
        to_receive[2].push_back(to_send[2][3]);
421
        to_receive[2].push_back(to_send[2][2]);
422
        to_receive[2].push_back(to_send[2][4]);
423
        to_receive[2].push_back(to_send[2][5]);
424
        to_receive[2].push_back(to_send[2][6]);
425
        to_receive[2].push_back(to_send[2][7]);
426
 
427
        //Test 4 - PassPW responses
428
        //Create a bunch of responses with different passPW values
429
        for(int n = 0; n < 8; n++){
430
                generate_random_forward_response_pkt(tb_pkt.pkt.packet);
431
                tb_pkt.pkt.packet[15] = (n == 0 || n == 1 || n == 4 || n == 5 || n == 7);
432
                to_send[3].push_back(tb_pkt);
433
        }
434
        to_receive[3].push_back(to_send[3][0]);
435
        to_receive[3].push_back(to_send[3][1]);
436
        to_receive[3].push_back(to_send[3][4]);
437
        to_receive[3].push_back(to_send[3][5]);
438
        to_receive[3].push_back(to_send[3][7]);
439
        to_receive[3].push_back(to_send[3][2]);
440
        to_receive[3].push_back(to_send[3][3]);
441
        to_receive[3].push_back(to_send[3][6]);
442
 
443
        //Run through the 4 tests
444
        for(int test = 0; test < 4; test++){
445
                //Send packets until they are all sent
446
                while(!to_send[test].empty()){
447
                        cd_available_ro = true;
448
                        cd_packet_ro = to_send[test].front().pkt;
449
                        to_send[test].pop_front();
450
                        wait();
451
                }
452
                cd_available_ro = false;
453
 
454
                //Wait for packets to reorganize
455
                for(int n = 0; n < 16; n++) wait();
456
 
457
                int idle = 0;
458
 
459
                //until all packet are ceived
460
                while(!to_receive[test].empty()){
461
                        //80% chance of reading the packet if available
462
                        read_fwd = (rand() % 10) < 8;
463
                        //If it is acked
464
                        if(fwd_ack_ro.read()){
465
                                idle = 0;
466
                                //display error if not the correct packet received
467
                                if(ro_packet_fwd.read().packet !=
468
                                        to_receive[test].front().pkt.packet)
469
                                {
470
                                        cout << "ERROR in reordering test: " << test << endl
471
                                                 << "    Received: " << ro_packet_fwd.read().packet.to_string(SC_HEX)
472
                                                 << " Expected: " << to_receive[test].front().pkt.packet.to_string(SC_HEX)
473
                                                 << endl;
474
                                        return;
475
                                }
476
                                to_receive[test].pop_front();
477
                        }
478
                        else{
479
                                //If read is active but no packet available, increment an idle counter to make
480
                                //sure the reordering doesn't just sit idle until the end of the simulation
481
                                if(read_fwd.read()){
482
                                        idle++;
483
                                }
484
                                if(idle > 5){
485
                                        cout << "ERROR: reordering idle for too long in test: " << test << endl;
486
                                        return;
487
                                }
488
                        }
489
                        wait();
490
                }
491
                read_fwd = false;
492
        }
493
        cout << "Test successful" << endl << endl;
494
 
495
        /////////////////////////////////////////
496
        // Test data packet not commited before
497
        // completely received
498
        /////////////////////////////////////////
499
        cout << "Test waiting for data to be commited"<< endl;
500
        cd_data_pending_ro = true;
501
        sc_uint<BUFFERS_ADDRESS_WIDTH> pending_addr = rand() % DATABUFFER_NB_BUFFERS;
502
        cd_data_pending_addr_ro = pending_addr;
503
        generate_random_posted_pkt(tb_pkt,POSTED_FORWARD);
504
        generate_random_64b_vector(tb_pkt.pkt.packet);
505
        //Posted write, not configured in BARs
506
        tb_pkt.pkt.packet.range(5,3) = "101";
507
 
508
        sc_bv<40> addr;
509
        generate_random_not_bar_address(addr);
510
        tb_pkt.pkt.packet.range(63,25) = addr.range(39,2);
511
 
512
        tb_pkt.pkt.data_address = pending_addr;
513
 
514
        cd_available_ro = true;
515
        cd_packet_ro = tb_pkt.pkt;
516
        read_ui = false;
517
        wait();
518
        cd_available_ro = false;
519
 
520
        for(int n = 0; n <5; n++){
521
                if(ro_available_fwd.read()){
522
                        cout << "ERROR: Packet sent out even if data not fully commited"<< endl;
523
                        return;
524
                }
525
                wait();
526
        }
527
 
528
        cd_data_pending_addr_ro = pending_addr + 1;
529
 
530
        bool received = false;
531
        read_ui = true;
532
        for(int n = 5; !received; n--){
533
                if(ro_available_fwd.read()) received = true;
534
                if(n == 0){
535
                        cout << "ERROR: Packet not sent out even if data fully commited"<< endl;
536
                        return;
537
                }
538
                wait();
539
        }
540
        read_ui = false;
541
        cout << "Test successful" << endl << endl;
542
 
543
        /////////////////////////////////////////
544
        // Test directroute
545
        /////////////////////////////////////////
546
 
547
        cout << "Test DirectRoute" << endl ;
548
 
549
        csr_direct_route_enable =    "00000000000001110000000000000000";
550
 
551
        generate_random_64b_vector(tb_pkt.pkt.packet);
552
        //Write to bar address
553
        int bar = rand() % NbRegsBars;
554
        tb_pkt.pkt.packet.range(5,3) = "101";
555
        tb_pkt.pkt.packet.range(63,63-Header_BarLength[bar] + 1) =
556
                csr_bar[bar].read().range(39,Header_BarSlotSize[bar]);
557
        //Don't want compat on
558
        tb_pkt.pkt.packet[21] = 0;
559
        //make it from 
560
        tb_pkt.pkt.packet.range(12,8) = sc_uint<5>(17);
561
        //adjust if chain
562
        tb_pkt.pkt.packet[19] = false;
563
        tb_pkt.pkt.error64BitExtension = false;
564
 
565
        cd_available_ro = true;
566
        cd_packet_ro = tb_pkt.pkt;
567
        read_ui = false;
568
        wait();
569
        cd_available_ro = false;
570
 
571
        received = false;
572
        read_ui = true;
573
        for(int n = 5; !received; n--){
574
                if(ro_available_ui.read()) received = true;
575
                if(n == 0){
576
                        cout << "ERROR: Packet not correctly directrouted to UI: "
577
                                << tb_pkt.pkt.packet.to_string(SC_HEX) << endl;
578
                        return;
579
                }
580
                wait();
581
        }
582
        read_ui = false;
583
        csr_direct_route_enable =    "00000000000000000000000000000000";
584
 
585
        cout << "Test successful" << endl << endl;
586
 
587
 
588
 
589
        /////////////////////////////////////////
590
        // Test overflow
591
        /////////////////////////////////////////
592
 
593
        cout << "Test overflow" << endl;
594
 
595
        generate_random_posted_pkt(tb_pkt,POSTED_ANY);
596
        cd_packet_ro = tb_pkt.pkt;
597
        read_ui = false;
598
        read_fwd = false;
599
        read_csr = false;
600
        for(int n = 0; n < 9; n++){
601
                cd_available_ro = true;
602
                wait();
603
        }
604
 
605
        for(int n = 0; n <3; n++){
606
                if(ro_overflow_csr.read()){
607
                        cout << "Buffer overflow activated without real overflow" << endl;
608
                        return;
609
                }
610
        }
611
        cd_available_ro = true;
612
        wait();
613
        cd_available_ro = false;
614
 
615
        bool got_overflow = false;
616
        for(int n = 0; !got_overflow; n++){
617
                if(ro_overflow_csr.read()){
618
                        got_overflow = true;
619
                }
620
                if(n > 3){
621
                        cout << "Buffer overflow not activated with real overflow" << endl;
622
                        return;
623
                }
624
        }
625
        cout << "Test successful" << endl << endl;
626
 
627
        /////////////////////////////////////////
628
        // Test buffer count features
629
        /////////////////////////////////////////
630
 
631
        resetx = false;
632
        for(int n = 0; n <3; n++) wait();
633
        resetx = true;
634
 
635
        /////////////////////////////////////////
636
        // Test clearing buffer status in retry mode
637
        /////////////////////////////////////////
638
 
639
        /////////////////////////////////////////
640
        // Test disabling reordering
641
        /////////////////////////////////////////
642
 
643
        //not done
644
 
645
        /////////////////////////////////////////
646
        // Test io and memory space enable
647
        /////////////////////////////////////////
648
 
649
        //not done
650
 
651
        /////////////////////////////////////////
652
        // Send the three types (p,np,r)
653
        /////////////////////////////////////////
654
 
655
        //not done
656
 
657
}
658
 
659
void reordering_l2_tb::consume_data(){
660
        csr_ack_ro = ro_available_csr.read() && read_csr.read();
661
        ui_ack_ro = ro_available_ui.read() && read_ui.read();
662
        fwd_ack_ro = ro_available_fwd.read() && read_fwd.read();
663
}
664
 
665
 
666
void reordering_l2_tb::generate_random_posted_pkt(ReorderTBPacket &tb_pkt,
667
                                                                                                 PostedType posted_type){
668
        tb_pkt.csr = false;
669
 
670
        switch(posted_type){
671
        case POSTED_ACCEPTED:
672
                tb_pkt.csr = generate_random_accepted_posted_pkt(tb_pkt.pkt.packet,false);
673
                tb_pkt.accepted = true;
674
                tb_pkt.forward = false;
675
                tb_pkt.pkt.error64BitExtension = false;
676
                break;
677
        case POSTED_FORWARD:
678
                generate_random_forward_posted_pkt(tb_pkt.pkt.packet,false);
679
                tb_pkt.accepted = false;
680
                tb_pkt.forward = true;
681
                tb_pkt.pkt.error64BitExtension = rand() % 2;
682
                break;
683
        default:
684
                int type = rand()%3;
685
                if(type == 0){
686
                        tb_pkt.csr = generate_random_accepted_posted_pkt(tb_pkt.pkt.packet,false);
687
                        tb_pkt.accepted = true;
688
                        tb_pkt.forward = false;
689
                        tb_pkt.pkt.error64BitExtension = false;
690
                }
691
                else if(type == 1){
692
                        generate_random_forward_posted_pkt(tb_pkt.pkt.packet,false);
693
                        tb_pkt.accepted = false;
694
                        tb_pkt.forward = true;
695
                        tb_pkt.pkt.error64BitExtension = rand() % 2;
696
                }
697
                else{
698
                        generate_random_broadcast_posted_pkt(tb_pkt.pkt.packet);
699
                        tb_pkt.accepted = true;
700
                        tb_pkt.forward = true;
701
                        tb_pkt.pkt.error64BitExtension = false;
702
                }
703
        }
704
 
705
        tb_pkt.pkt.isPartOfChain = false;
706
        tb_pkt.pkt.data_address = sc_uint<32>(rand()).range(BUFFERS_ADDRESS_WIDTH-1,0);
707
}
708
 
709
bool reordering_l2_tb::generate_random_accepted_posted_pkt(sc_bv<64> &pkt,
710
                                                                                                                  bool chain){
711
        //Randomly generate a 64-bit packet
712
        generate_random_64b_vector(pkt);
713
        //Now, we'll choose where the packet goes and set some of the bits accordingly
714
        //Choose a type randomly :
715
        // 0 : goes to CSR
716
        // 1 : goes to user (normal traffic)
717
        // 2 : goes to user (device message)
718
        int type = rand() % 3;
719
 
720
        //If in the middle of the chain
721
        if(curently_sending_chain){
722
                //Set the new value depending on if a chain packet is selected
723
                curently_sending_chain = chain;
724
                //Set same type as before
725
                if(chain_destination = POSTED_DESTINATION_CSR) type = 0;
726
                else if(chain_destination = POSTED_DESTINATION_USER) type = 1;
727
                else type = 2;
728
        }
729
        else if(chain){
730
                if(type == 0) chain_destination = POSTED_DESTINATION_CSR;
731
                else if(type == 1) chain_destination = POSTED_DESTINATION_USER;
732
                else chain_destination = POSTED_DESTINATION_USER_DEVICE_MSG;
733
        }
734
 
735
        //Go to CSR if the type is 0
736
        int csr = type == 0;
737
 
738
        pkt.range(5,3) = "101";
739
        if(type == 0){
740
                //CSR write
741
                pkt.range(63,48) =
742
                        "1111110111111110";
743
                pkt.range(39,35) = csr_unit_id.read();
744
        }
745
        else if(type == 1 || chain){
746
                //Write to bar address
747
                int bar = rand() % NbRegsBars;
748
                pkt.range(63,63-Header_BarLength[bar] + 1) =
749
                        csr_bar[bar].read().range(39,Header_BarSlotSize[bar]);
750
 
751
        }
752
        else{
753
                //Device message
754
                pkt.range(63,52) =
755
                        "111111100000";
756
                pkt.range(39,35) = csr_unit_id.read();
757
                pkt[2] = true;//always byte
758
        }
759
        //Don't want compat on
760
        pkt[21] = 0;
761
        //make it downstream
762
        pkt.range(12,8) = 0;
763
        //adjust if chain
764
        pkt[19] = chain;
765
        return csr;
766
}
767
 
768
void reordering_l2_tb::generate_random_forward_posted_pkt(sc_bv<64> &pkt, bool chain){
769
        generate_random_64b_vector(pkt);
770
        int type = rand()%2;
771
        if(type || chain){
772
                //Posted write, not configured in BARs
773
                pkt.range(5,3) = "101";
774
 
775
                sc_bv<40> addr;
776
                generate_random_not_bar_address(addr);
777
                pkt.range(63,25) = addr.range(39,2);
778
 
779
        }
780
        else{
781
                //Posted fence
782
                pkt.range(5,0) = "111100";
783
        }
784
        pkt[19] = chain;
785
}
786
 
787
void reordering_l2_tb::generate_random_broadcast_posted_pkt(sc_bv<64> &pkt){
788
        generate_random_64b_vector(pkt);
789
        pkt.range(5,0) = "111010";
790
}
791
 
792
void reordering_l2_tb::generate_random_64b_vector(sc_bv<64> &pkt){
793
        sc_uint<32> r;
794
        for(int n = 0; n < 4;n++){
795
                r = rand();
796
                pkt(15*(n+1)-1,15*n) = sc_uint<32>(rand()).range(14,0);
797
        }
798
        r = rand();
799
        pkt(63,60) = sc_uint<32>(rand()).range(3,0);
800
}
801
 
802
bool reordering_l2_tb::generate_random_accepted_nposted_pkt(sc_bv<64> &pkt){
803
        generate_random_64b_vector(pkt);
804
        int type = rand() % 3;
805
        int csr = rand() % 2;
806
 
807
        if(type == 0){
808
                //Non posted write
809
                pkt.range(5,3) = "001";
810
        }
811
        else if(type == 1){
812
                //Read
813
                pkt.range(5,4) = "01";
814
        }
815
        else{
816
                //Atomic
817
                pkt.range(5,0) = "0111101";
818
        }
819
        //Don't want compat on
820
        pkt[21] = 0;
821
        //make it downstream
822
        pkt.range(12,8) = 0;
823
 
824
        //If CSR, adjust address
825
        if(csr){
826
                pkt.range(63,48) =
827
                        "1111110111111110";
828
                pkt.range(39,35) = csr_unit_id.read();
829
        }
830
        else{
831
                int bar = rand() % NbRegsBars;
832
                pkt.range(63,63-Header_BarLength[bar] + 1) =
833
                        csr_bar[bar].read().range(39,Header_BarSlotSize[bar]);
834
        }
835
        return csr;
836
}
837
 
838
void reordering_l2_tb::generate_random_nposted_pkt(ReorderTBPacket &tb_pkt,
839
                                                                                                 NPostedType nposted_type){
840
        tb_pkt.csr = false;
841
 
842
        switch(nposted_type){
843
        case NPOSTED_ACCEPTED:
844
                tb_pkt.csr = generate_random_accepted_nposted_pkt(tb_pkt.pkt.packet);
845
                tb_pkt.accepted = true;
846
                tb_pkt.forward = false;
847
                tb_pkt.pkt.error64BitExtension = false;
848
                break;
849
        case NPOSTED_FORWARD:
850
                generate_random_forward_nposted_pkt(tb_pkt.pkt.packet);
851
                tb_pkt.accepted = false;
852
                tb_pkt.forward = true;
853
                tb_pkt.pkt.error64BitExtension = rand() % 2;
854
                break;
855
        default:
856
                int type = rand()%2;
857
                if(type == 0){
858
                        tb_pkt.csr = generate_random_accepted_nposted_pkt(tb_pkt.pkt.packet);
859
                        tb_pkt.accepted = true;
860
                        tb_pkt.forward = false;
861
                        tb_pkt.pkt.error64BitExtension = false;
862
                }
863
                else{
864
                        generate_random_forward_nposted_pkt(tb_pkt.pkt.packet);
865
                        tb_pkt.accepted = false;
866
                        tb_pkt.forward = true;
867
                        tb_pkt.pkt.error64BitExtension = rand() % 2;
868
                }
869
        }
870
 
871
        tb_pkt.pkt.isPartOfChain = false;
872
        tb_pkt.pkt.data_address = sc_uint<32>(rand()).range(BUFFERS_ADDRESS_WIDTH-1,0);
873
}
874
 
875
void reordering_l2_tb::generate_random_forward_nposted_pkt(sc_bv<64> &pkt){
876
        generate_random_64b_vector(pkt);
877
        sc_bv<40> addr;
878
        generate_random_not_bar_address(addr);
879
 
880
        int type = rand()%4;
881
        switch(type){
882
        case 0:
883
                //flush
884
                pkt.range(5,0) = "000010";
885
                break;
886
        case 1:
887
                //Non posted write
888
                pkt.range(5,3) = "001";
889
                pkt.range(63,26) = addr.range(39,2);
890
                break;
891
        case 2:
892
                //Read
893
                pkt.range(5,4) = "01";
894
                pkt.range(63,26) = addr.range(39,2);
895
                break;
896
        default:
897
                //Atomic
898
                pkt.range(5,0) = "0111101";
899
                pkt.range(63,27) = addr.range(39,3);
900
        }
901
}
902
 
903
void reordering_l2_tb::generate_random_not_bar_address(sc_bv<40> &addr){
904
        //Generate random adresses until we find one not in bars
905
        /**
906
                Probably not the most efficient way of doing this!!!  But it's quick
907
                to code and it works.  Care must be taken that the majority of the address
908
                space is not used by BARs!
909
        */
910
        bool in_bar;
911
        do{
912
                //Generate random address
913
                addr.range(9,0) = sc_uint<32>(rand()).range(9,0);
914
                addr.range(34,10) = sc_uint<32>(rand()).range(14,0);
915
                addr.range(39,35) = sc_uint<32>(rand()).range(14,0);
916
 
917
                //Check if it in bar
918
                in_bar = false;
919
                for(int n = 0; n < NbRegsBars; n++){
920
                        if(             addr.range(39,Header_BarSlotSize[n]) ==
921
                                        csr_bar[n].read().range(39,Header_BarSlotSize[n])
922
                                ) in_bar = true;
923
                }
924
        //Repeat procedure until we have an address not in the bar
925
        }while(in_bar);
926
}
927
 
928
void reordering_l2_tb::generate_random_accepted_response_pkt(sc_bv<64> &pkt){
929
        generate_random_64b_vector(pkt);
930
        pkt.range(63,32) = 0;
931
        int type = rand() % 2;
932
        if(type){
933
                //Read response
934
                pkt.range(5,0) = "110000";
935
        }
936
        else{
937
                //Target done
938
                pkt.range(5,0) = "110011";
939
        }
940
        //bridge bit set
941
        pkt[14] = true;
942
        //unit_id owned by the node
943
        pkt.range(12,8) = csr_unit_id.read();
944
 
945
}
946
 
947
void reordering_l2_tb::generate_random_response_pkt(ReorderTBPacket &tb_pkt,
948
                                                                                                 ResponseType response_type){
949
 
950
        switch(response_type){
951
        case RESPONSE_ACCEPTED:
952
                generate_random_accepted_response_pkt(tb_pkt.pkt.packet);
953
                tb_pkt.accepted = true;
954
                tb_pkt.forward = false;
955
                tb_pkt.pkt.error64BitExtension = false;
956
                break;
957
        case NPOSTED_FORWARD:
958
                generate_random_forward_response_pkt(tb_pkt.pkt.packet);
959
                tb_pkt.accepted = false;
960
                tb_pkt.forward = true;
961
                tb_pkt.pkt.error64BitExtension = rand() % 2;
962
                break;
963
        default:
964
                int type = rand()%2;
965
                if(type == 0){
966
                        generate_random_accepted_response_pkt(tb_pkt.pkt.packet);
967
                        tb_pkt.accepted = true;
968
                        tb_pkt.forward = false;
969
                        tb_pkt.pkt.error64BitExtension = false;
970
                }
971
                else{
972
                        generate_random_forward_response_pkt(tb_pkt.pkt.packet);
973
                        tb_pkt.accepted = false;
974
                        tb_pkt.forward = true;
975
                        tb_pkt.pkt.error64BitExtension = rand() % 2;
976
                }
977
        }
978
 
979
        tb_pkt.csr = false;
980
        tb_pkt.pkt.isPartOfChain = false;
981
        tb_pkt.pkt.data_address = sc_uint<32>(rand()).range(BUFFERS_ADDRESS_WIDTH-1,0);
982
 
983
}
984
 
985
void reordering_l2_tb::generate_random_forward_response_pkt(sc_bv<64> &pkt){
986
        generate_random_accepted_response_pkt(pkt);
987
        pkt.range(63,32) = 0;
988
 
989
        int forward_cause = rand() % 3;
990
        if(forward_cause == 0 || forward_cause == 2){
991
                //bridge bit unset
992
                pkt[14] = false;
993
        }
994
        if(forward_cause == 1 || forward_cause == 2){
995
        //unit_id owned by the node
996
        pkt.range(12,8) = ~csr_unit_id.read();
997
        }
998
}
999
 
1000
void reordering_l2_tb::manage_memories(){
1001
                ////////////////////////////////////
1002
                // CoommandBuffer Memories
1003
                ////////////////////////////////////
1004
                for(int n = 0; n < 2; n++){
1005
                        command_packet_rd_data_ro[n] =
1006
                                command_memory[ro_command_packet_rd_addr[n].read().to_int()];
1007
                }
1008
 
1009
                if(ro_command_packet_write.read())
1010
                        command_memory[ro_command_packet_wr_addr.read().to_int()] =
1011
                                ro_command_packet_wr_data.read();
1012
}

powered by: WebSVN 2.1.0

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