OpenCores
URL https://opencores.org/ocsvn/an-fpga-implementation-of-low-latency-noc-based-mpsoc/an-fpga-implementation-of-low-latency-noc-based-mpsoc/trunk

Subversion Repositories an-fpga-implementation-of-low-latency-noc-based-mpsoc

[/] [an-fpga-implementation-of-low-latency-noc-based-mpsoc/] [trunk/] [mpsoc/] [src_c/] [netrace-1.0/] [netrace.c] - Blame information for rev 48

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 48 alirezamon
/*
2
 * Copyright (c) 2010-2011 The University of Texas at Austin
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are
7
 * met: redistributions of source code must retain the above copyright
8
 * notice, this list of conditions and the following disclaimer;
9
 * redistributions in binary form must reproduce the above copyright
10
 * notice, this list of conditions and the following disclaimer in the
11
 * documentation and/or other materials provided with the distribution;
12
 * neither the name of the copyright holders nor the names of its
13
 * contributors may be used to endorse or promote products derived from
14
 * this software without specific prior written permission.
15
 *
16
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
 */
28
 
29
#include "netrace.h"
30
 
31
char*                           nt_input_popencmd;
32
FILE*                           nt_input_tracefile;
33
char*                           nt_input_buffer;
34
nt_header_t*            nt_input_trheader;
35
int                                     nt_dependencies_off;
36
int                                     nt_self_throttling;
37
int                                     nt_primed_self_throttle;
38
int                                     nt_done_reading;
39
unsigned long long int nt_latest_active_packet_cycle;
40
nt_dep_ref_node_t** nt_dependency_array;
41
unsigned long long int nt_num_active_packets;
42
const char* nt_packet_types[] = { "InvalidCmd", "ReadReq", "ReadResp",
43
                                "ReadRespWithInvalidate", "WriteReq", "WriteResp",
44
                                "Writeback", "InvalidCmd", "InvalidCmd", "InvalidCmd",
45
                                "InvalidCmd", "InvalidCmd", "InvalidCmd", "UpgradeReq",
46
                                "UpgradeResp", "ReadExReq", "ReadExResp", "InvalidCmd",
47
                                "InvalidCmd", "InvalidCmd", "InvalidCmd", "InvalidCmd",
48
                                "InvalidCmd", "InvalidCmd", "InvalidCmd", "BadAddressError",
49
                                "InvalidCmd", "InvalidateReq", "InvalidateResp",
50
                                "DowngradeReq", "DowngradeResp" };
51
 
52
int nt_packet_sizes[] = { /*InvalidCmd*/ -1, /*ReadReq*/ 8, /*ReadResp*/ 72,
53
                                /*ReadRespWithInvalidate*/ 72, /*WriteReq*/ 72, /*WriteResp*/ 8,
54
                                /*Writeback*/ 72, /*InvalidCmd*/ -1, /*InvalidCmd*/ -1, /*InvalidCmd*/ -1,
55
                                /*InvalidCmd*/ -1, /*InvalidCmd*/ -1, /*InvalidCmd*/ -1, /*UpgradeReq*/ 8,
56
                                /*UpgradeResp*/ 8, /*ReadExReq*/ 8, /*ReadExResp*/ 72, /*InvalidCmd*/ -1,
57
                                /*InvalidCmd*/ -1, /*InvalidCmd*/ -1, /*InvalidCmd*/ -1, /*InvalidCmd*/ -1,
58
                                /*InvalidCmd*/ -1, /*InvalidCmd*/ -1, /*InvalidCmd*/ -1, /*BadAddressError*/ 8,
59
                                /*InvalidCmd*/ -1, /*InvalidateReq*/ 8, /*InvalidateResp*/ 8,
60
                                /*DowngradeReq*/ 8, /*DowngradeResp*/ 72 };
61
 
62
const char* nt_node_types[] = { "L1 Data Cache", "L1 Instruction Cache",
63
                                "L2 Cache", "Memory Controller", "Invalid Node Type" };
64
 
65
nt_packet_list_t*       nt_cleared_packets_list;
66
nt_packet_list_t*       nt_cleared_packets_list_tail;
67
int nt_track_cleared_packets_list;
68
 
69
void nt_open_trfile(  char* trfilename ) {
70
        nt_close_trfile();
71
        int i;
72
        int length = 20;
73
        for( i = 0; trfilename[i] != 0; i++, length++ );
74
        nt_input_popencmd = (char*) nt_checked_malloc( length * sizeof(char) );
75
        sprintf( nt_input_popencmd, "bzip2 -dc %s", trfilename );
76
        nt_input_tracefile = popen( nt_input_popencmd, "r" );
77
        if( nt_input_tracefile == NULL ) {
78
                nt_error( "failed to open pipe to trace file" );
79
        }
80
        nt_input_trheader = nt_read_trheader();
81
        if( nt_dependency_array == NULL ) {
82
                nt_dependency_array = (nt_dep_ref_node_t**) nt_checked_malloc( sizeof(nt_dep_ref_node_t*) * NT_DEPENDENCY_ARRAY_SIZE );
83
                memset( nt_dependency_array, 0, sizeof(nt_dep_ref_node_t*) * NT_DEPENDENCY_ARRAY_SIZE );
84
                nt_num_active_packets = 0;
85
        } else {
86
                nt_error( "dependency array not NULL on file open" );
87
        }
88
}
89
 
90
nt_header_t* nt_read_trheader() {
91
 
92
        #pragma pack(push,1)
93
        struct nt_header_pack {
94
                unsigned int nt_magic;
95
                float version;
96
                char benchmark_name[NT_BMARK_NAME_LENGTH];
97
                unsigned char num_nodes;
98
                unsigned char pad;
99
                unsigned long long int num_cycles;
100
                unsigned long long int num_packets;
101
                unsigned int notes_length;  // Includes null-terminating char
102
                unsigned int num_regions;
103
                char padding[8];
104
        };
105
        #pragma pack(pop)
106
 
107
        int err = 0;
108
        char strerr[180];
109
 
110
        // Read Header
111
        struct nt_header_pack* in_header = (struct nt_header_pack*)nt_checked_malloc( sizeof(struct nt_header_pack) );
112
        fseek( nt_input_tracefile, 0, SEEK_SET );
113
        if( (err = fread( in_header, sizeof(struct nt_header_pack), 1, nt_input_tracefile )) < 0 ) {
114
                sprintf( strerr, "failed to read trace file header: err = %d", err );
115
                nt_error( strerr );
116
        }
117
 
118
        // Copy data from struct to header
119
        nt_header_t* to_return = (nt_header_t*) nt_checked_malloc( sizeof(nt_header_t) );
120
        memset( to_return, 0, sizeof(nt_header_t) );
121
        to_return->nt_magic = in_header->nt_magic;
122
        to_return->version = in_header->version;
123
        strcpy( to_return->benchmark_name, in_header->benchmark_name );
124
        to_return->num_nodes = in_header->num_nodes;
125
        to_return->num_cycles = in_header->num_cycles;
126
        to_return->num_packets = in_header->num_packets;
127
        to_return->notes_length = in_header->notes_length;
128
        to_return->num_regions = in_header->num_regions;
129
        free( in_header );
130
 
131
        // Error Checking
132
        if( to_return->nt_magic != NT_MAGIC ) {
133
                if( nt_little_endian() != 1 ) {
134
                        nt_error( "only little endian architectures are currently supported" );
135
                } else {
136
                        nt_error( "invalid trace file: bad magic" );
137
                }
138
        }
139
        if( to_return->version != 1.0f ) {
140
                sprintf( strerr, "trace file is unsupported version: %f", to_return->version );
141
                nt_error( strerr );
142
        }
143
        // Read Rest of Header
144
        if( to_return->notes_length > 0 && to_return->notes_length < 8192 ) {
145
                to_return->notes = (char*) nt_checked_malloc( to_return->notes_length * sizeof(char) );
146
                if( (err = fread( to_return->notes, sizeof(char), to_return->notes_length, nt_input_tracefile )) < 0 ) {
147
                        sprintf( strerr, "failed to read trace file header notes: err = %d\n", err );
148
                        nt_error( strerr );
149
                }
150
        } else {
151
                to_return->notes = NULL;
152
        }
153
        if( to_return->num_regions > 0 ) {
154
                if( to_return->num_regions <= 100 ) {
155
                        to_return->regions = (nt_regionhead_t*) nt_checked_malloc( to_return->num_regions * sizeof(nt_regionhead_t) );
156
                        if( (err = fread( to_return->regions, sizeof(nt_regionhead_t), to_return->num_regions, nt_input_tracefile )) < 0 ) {
157
                                sprintf( strerr, "failed to read trace file header regions: error = %d\n", err );
158
                                nt_error( strerr );
159
                        }
160
                } else {
161
                        nt_error( "lots of regions... is this correct?" );
162
                }
163
        } else {
164
                to_return->regions = NULL;
165
        }
166
        return to_return;
167
}
168
 
169
void nt_disable_dependencies() {
170
        if( nt_track_cleared_packets_list ) {
171
                nt_error( "Cannot turn off dependencies when tracking cleared packets list" );
172
        }
173
        nt_dependencies_off = 1;
174
}
175
 
176
void nt_seek_region( nt_regionhead_t* region ) {
177
        int err = 0;
178
        char strerr[180];
179
        if( nt_input_tracefile != NULL ) {
180
                if( region != NULL ) {
181
                        // Clear all existing dependencies
182
                        nt_delete_all_dependencies();
183
                        // Reopen file to fast-forward to region
184
                        // fseek doesn't work on compressed file
185
                        pclose( nt_input_tracefile );
186
                        nt_input_tracefile = popen( nt_input_popencmd, "r" );
187
            unsigned long long int seek_offset = nt_get_headersize() + region->seek_offset;
188
            unsigned long long int read_length = 4096;
189
                        char* buffer = (char*) nt_checked_malloc( read_length );
190
                        while( seek_offset > read_length ) {
191
                                if( (err = fread( buffer, 1, read_length, nt_input_tracefile )) < 0 ) {
192
                                        sprintf( strerr, "failed to seek region: error = %d\n", err );
193
                                        nt_error( strerr );
194
                                }
195
                                seek_offset -= read_length;
196
                        }
197
                        if( (err = fread( buffer, 1, seek_offset, nt_input_tracefile )) < 0 ) {
198
                                sprintf( strerr, "failed to seek region: error = %d\n", err );
199
                                nt_error( strerr );
200
                        }
201
                        free( buffer );
202
                        if( nt_self_throttling ) {
203
                                // Prime the pump to read in self throttled packets
204
                                nt_prime_self_throttle();
205
                        }
206
                } else {
207
                        nt_error( "invalid region passed: NULL" );
208
                }
209
        } else {
210
                nt_error( "must open trace file with nt_open_trfile before seeking" );
211
        }
212
}
213
 
214
nt_packet_t* nt_read_packet( void ) {
215
 
216
        #pragma pack(push,1)
217
        struct nt_packet_pack {
218
                unsigned long long int cycle;
219
                unsigned int id;
220
                unsigned int addr;
221
                unsigned char type;
222
                unsigned char src;
223
                unsigned char dst;
224
                unsigned char node_types;
225
                unsigned char num_deps;
226
        };
227
        #pragma pack(pop)
228
 
229
        int err = 0;
230
        unsigned int i;
231
        char strerr[180];
232
        nt_packet_t* to_return = NULL;
233
        if( nt_input_tracefile != NULL ) {
234
                to_return = nt_packet_malloc();
235
                if( (err = fread( to_return, 1, sizeof(struct nt_packet_pack), nt_input_tracefile )) < 0 ) {
236
                        sprintf( strerr, "failed to read packet: err = %d", err );
237
                        nt_error( strerr );
238
                }
239
                if( err > 0 && err < (int) sizeof(struct nt_packet_pack) ) {
240
                        // Bad packet - end of file
241
                        nt_error( "unexpectedly reached end of trace file - perhaps corrupt" );
242
                } else if( err == 0 ) {
243
                        // End of file
244
                        free( to_return );
245
                        to_return = NULL;
246
                        return to_return;
247
                }
248
 
249
                if( !nt_dependencies_off ) {
250
                        // Track dependencies: add to_return to dependencies array
251
                        nt_dep_ref_node_t* node_ptr = nt_get_dependency_node( to_return->id );
252
                        if( node_ptr == NULL ) {
253
                                node_ptr = nt_add_dependency_node( to_return->id );
254
                        }
255
                        node_ptr->node_packet = to_return;
256
                }
257
                nt_num_active_packets++;
258
                nt_latest_active_packet_cycle = to_return->cycle;
259
                if( to_return->num_deps == 0 ) {
260
                        to_return->deps = NULL;
261
                } else {
262
                        to_return->deps = nt_dependency_malloc( to_return->num_deps );
263
                        if( (err = fread( to_return->deps, sizeof(nt_dependency_t), to_return->num_deps, nt_input_tracefile )) < 0 ) {
264
                                sprintf( strerr, "failed to read dependencies: err = %d", err );
265
                                nt_error( strerr );
266
                        }
267
                        if( !nt_dependencies_off ) {
268
                                // Track dependencies: add to_return downward dependencies to array
269
                                for( i = 0; i < to_return->num_deps; i++ ) {
270
                                        unsigned int dep_id = to_return->deps[i];
271
                                        nt_dep_ref_node_t* node_ptr = nt_get_dependency_node( dep_id );
272
                                        if( node_ptr == NULL ) {
273
                                                node_ptr = nt_add_dependency_node( dep_id );
274
                                        }
275
                                        node_ptr->ref_count++;
276
                                }
277
                        }
278
                }
279
        } else {
280
                nt_error( "must open trace file with nt_open_trfile before reading" );
281
        }
282
 
283
        return to_return;
284
}
285
 
286
nt_dep_ref_node_t* nt_add_dependency_node( unsigned int packet_id ) {
287
        if( nt_dependency_array != NULL ) {
288
                unsigned int index = packet_id % NT_DEPENDENCY_ARRAY_SIZE;
289
                nt_dep_ref_node_t* dep_ptr = nt_dependency_array[index];
290
                if( dep_ptr == NULL ) {
291
                        nt_dependency_array[index] = (nt_dep_ref_node_t*) nt_checked_malloc( sizeof(nt_dep_ref_node_t) );
292
                        dep_ptr = nt_dependency_array[index];
293
                } else {
294
                        for( ; dep_ptr->next_node != NULL; dep_ptr = dep_ptr->next_node );
295
                        dep_ptr->next_node =(nt_dep_ref_node_t*) nt_checked_malloc( sizeof(nt_dep_ref_node_t) );
296
                        dep_ptr = dep_ptr->next_node;
297
                }
298
                dep_ptr->node_packet = NULL;
299
                dep_ptr->packet_id = packet_id;
300
                dep_ptr->ref_count = 0;
301
                dep_ptr->next_node = NULL;
302
                return dep_ptr;
303
        } else {
304
                nt_error( "dependency array NULL on node addition" );
305
        }
306
        return NULL;
307
}
308
 
309
void nt_read_ahead( unsigned long long int current_cycle ) {
310
        unsigned long long int read_to_cycle = current_cycle + NT_READ_AHEAD;
311
        if( read_to_cycle < current_cycle ) {
312
                nt_error( "trying to read too far ahead... overflowed :(" );
313
        }
314
        if( read_to_cycle > nt_latest_active_packet_cycle ) {
315
                nt_packet_t* packet;
316
                int d= ((end_sim_pck_num == 0 ) || (end_sim_pck_num > nt_tr_list_pck ));
317
                while( nt_latest_active_packet_cycle <= read_to_cycle && !nt_done_reading && (d==1) ) {
318
                        packet = nt_read_packet();
319
                        nt_tr_list_pck++;
320
                        //printf("nt_tr_list_pck=%u\n",nt_tr_list_pck);
321
                        if( packet == NULL ) {
322
                                // This is the exit condition... how do we signal it to the
323
                                // network simulator? We shouldn't need to... It is tracking
324
                                // whether there are packets in flight.
325
                                // Just in case, we'll provide this global indicator
326
                                nt_done_reading = 1;
327
                        } else if( nt_dependencies_cleared( packet ) ) {
328
                                nt_add_cleared_packet_to_list( packet );
329
 
330
                        //} else {
331
                                // Ignore this packet, since the reader is already tracking it
332
                        }
333
                }
334
        }
335
}
336
 
337
nt_packet_t* nt_remove_dependency_node( unsigned int packet_id ) {
338
        if( nt_dependency_array != NULL ) {
339
                unsigned int index = packet_id % NT_DEPENDENCY_ARRAY_SIZE;
340
                nt_dep_ref_node_t* dep_ptr = nt_dependency_array[index];
341
                if( dep_ptr == NULL ) {
342
                        return NULL;
343
                } else {
344
                        nt_dep_ref_node_t* prev_ptr = NULL;
345
                        for( ; dep_ptr != NULL; prev_ptr = dep_ptr, dep_ptr = dep_ptr->next_node ) {
346
                                if( dep_ptr->packet_id == packet_id ) break;
347
                        }
348
                        if( dep_ptr == NULL ) {
349
                                return NULL;
350
                        }
351
                        if( prev_ptr == NULL ) {
352
                                nt_dependency_array[index] = dep_ptr->next_node;
353
                        } else {
354
                                prev_ptr->next_node = dep_ptr->next_node;
355
                        }
356
                        nt_packet_t* packet = dep_ptr->node_packet;
357
                        free( dep_ptr );
358
                        return packet;
359
                }
360
        } else {
361
                nt_error( "dependency array NULL on node remove" );
362
        }
363
        return NULL;
364
}
365
 
366
nt_dep_ref_node_t* nt_get_dependency_node( unsigned int packet_id ) {
367
        if( nt_dependency_array != NULL ) {
368
                unsigned int index = packet_id % NT_DEPENDENCY_ARRAY_SIZE;
369
                nt_dep_ref_node_t* dep_ptr;
370
                for( dep_ptr = nt_dependency_array[index]; dep_ptr != NULL; dep_ptr = dep_ptr->next_node ) {
371
                        if( dep_ptr->packet_id == packet_id ) break;
372
                }
373
                return dep_ptr;
374
        } else {
375
                nt_error( "dependency array not NULL on node search" );
376
        }
377
        return NULL;
378
}
379
 
380
int nt_dependencies_cleared( nt_packet_t* packet ) {
381
        if( nt_input_tracefile != NULL ) {
382
                nt_dep_ref_node_t* node_ptr = nt_get_dependency_node( packet->id );
383
                if( node_ptr == NULL || nt_dependencies_off ) {
384
                        return 1;
385
                } else {
386
                        return (node_ptr->ref_count == 0);
387
                }
388
        } else {
389
                nt_error( "must open trace file with nt_open_trfile before injecting" );
390
        }
391
        return 1;
392
}
393
 
394
void nt_clear_dependencies_free_packet( nt_packet_t* packet ) {
395
        unsigned int i;
396
        if( nt_input_tracefile != NULL ) {
397
                if( packet != NULL ) {
398
                        // If self-throttling, read ahead in the trace file
399
                        // to ensure that there are new packets ready to go
400
                        if( nt_self_throttling ) {
401
                                nt_read_ahead( packet->cycle );
402
                        }
403
                        for( i = 0; i < packet->num_deps; i++ ) {
404
                                unsigned int dep_id = packet->deps[i];
405
                                nt_dep_ref_node_t* node_ptr = nt_get_dependency_node( dep_id );
406
                                if( node_ptr == NULL ) {
407
                                        if( !nt_dependencies_off ) {
408
                                                // TODO: check if this is a problem with short seeks
409
                                                nt_print_packet( packet );
410
                                                nt_error( "failed to find dependency node" );
411
                                        }
412
                                } else {
413
                                        if( node_ptr->ref_count == 0 ) {
414
                                                nt_error( "invalid reference count on node while decrementing" );
415
                                        }
416
                                        node_ptr->ref_count--;
417
                                        if( nt_track_cleared_packets_list ) {
418
                                                if( node_ptr->ref_count == 0 ) {
419
                                                        // This test alleviates the possibility of a packet
420
                                                        // having ref_count zero before it has been read
421
                                                        // from the trace (node_packet = NULL)
422
                                                        if( node_ptr->node_packet ) {
423
                                                                nt_add_cleared_packet_to_list( node_ptr->node_packet );
424
                                                        }
425
                                                }
426
                                        }
427
                                }
428
                        }
429
                        nt_remove_dependency_node( packet->id );
430
                        nt_packet_free( packet );
431
                        nt_num_active_packets--;
432
                }
433
        } else {
434
                nt_error( "must open trace file with nt_open_trfile before ejecting" );
435
        }
436
}
437
 
438
void nt_init_cleared_packets_list() {
439
        if( nt_dependencies_off ) {
440
                nt_error( "Cannot return cleared packets list when dependencies are turned off" );
441
        }
442
        nt_track_cleared_packets_list = 1;
443
        nt_cleared_packets_list = NULL;
444
        nt_cleared_packets_list_tail = NULL;
445
}
446
 
447
void nt_init_self_throttling() {
448
        if( nt_dependencies_off ) {
449
                nt_error( "Cannot self throttle packets when dependencies are turned off" );
450
        }
451
        nt_self_throttling = 1;
452
        nt_primed_self_throttle = 0;
453
        nt_init_cleared_packets_list();
454
}
455
 
456
nt_packet_list_t* nt_get_cleared_packets_list() {
457
        if( !nt_primed_self_throttle ) {
458
                nt_prime_self_throttle();
459
        }
460
        return nt_cleared_packets_list;
461
}
462
 
463
void nt_prime_self_throttle() {
464
        nt_packet_t* packet = nt_read_packet();
465
    nt_tr_list_pck++;
466
        if( nt_dependencies_cleared( packet ) ) {
467
                nt_add_cleared_packet_to_list( packet );
468
        }
469
        nt_primed_self_throttle = 1;
470
        nt_read_ahead( packet->cycle );
471
}
472
 
473
void nt_add_cleared_packet_to_list( nt_packet_t* packet ) {
474
        nt_packet_list_t* new_node = (nt_packet_list_t*) nt_checked_malloc( sizeof(nt_packet_list_t) );
475
        new_node->node_packet = packet;
476
        new_node->next = NULL;
477
        if( nt_cleared_packets_list == NULL ) {
478
                nt_cleared_packets_list = nt_cleared_packets_list_tail = new_node;
479
        } else {
480
                nt_cleared_packets_list_tail->next = new_node;
481
                nt_cleared_packets_list_tail = new_node;
482
        }
483
}
484
 
485
void nt_empty_cleared_packets_list() {
486
        while( nt_cleared_packets_list != NULL ) {
487
                nt_packet_list_t* temp = nt_cleared_packets_list;
488
                nt_cleared_packets_list = nt_cleared_packets_list->next;
489
                free( temp );
490
        }
491
        nt_cleared_packets_list = nt_cleared_packets_list_tail = NULL;
492
}
493
 
494
void nt_close_trfile() {
495
        if( nt_input_tracefile != NULL ) {
496
                pclose( nt_input_tracefile );
497
                nt_input_tracefile = NULL;
498
                nt_free_trheader( nt_input_trheader );
499
                if( nt_input_popencmd != NULL ) {
500
                        free( nt_input_popencmd );
501
                }
502
                nt_input_popencmd = NULL;
503
                nt_delete_all_dependencies();
504
                free(nt_dependency_array);
505
                nt_dependency_array = NULL;
506
        }
507
}
508
 
509
void nt_delete_all_dependencies() {
510
        int i;
511
        for( i = 0; i < NT_DEPENDENCY_ARRAY_SIZE; i++ ) {
512
                while( nt_dependency_array[i] != NULL ) {
513
                        nt_remove_dependency_node( nt_dependency_array[i]->packet_id );
514
                }
515
        }
516
}
517
 
518
void nt_print_header( nt_header_t* header ) {
519
        unsigned int i;
520
        if( header != NULL ) {
521
                printf( "NT_TRACEFILE---------------------\n" );
522
 
523
                printf( "  Benchmark: %s\n", header->benchmark_name );
524
                printf( "  Magic Correct? %s\n", (header->nt_magic == NT_MAGIC) ? "TRUE" : "FALSE" );
525
                printf( "  Tracefile Version: v%1.1f\n", header->version );
526
                printf( "  Number of Program Regions: %d\n", header->num_regions );
527
                printf( "  Number of Simulated Nodes: %d\n", header->num_nodes );
528
                printf( "  Simulated Cycles: %lld\n", header->num_cycles );
529
                printf( "  Simulated Packets: %lld\n", header->num_packets );
530
                printf( "  Average injection rate: %f\n", (double)header->num_packets / (double)header->num_cycles );
531
                if( header->notes_length > 0 ) {
532
                        printf( "  Notes: %s\n", header->notes );
533
                }
534
 
535
                for( i = 0; i < header->num_regions; i++ ) {
536
                        printf( "    Region %d:\n", i );
537
                        printf( "      Seek Offset: %lld\n", header->regions[i].seek_offset );
538
                        printf( "      Simulated Cycles: %lld\n", header->regions[i].num_cycles );
539
                        printf( "      Simulated Packets: %lld\n", header->regions[i].num_packets );
540
                        printf( "      Average injection rate: %f\n", (double)header->regions[i].num_packets / (double)header->regions[i].num_cycles );
541
                        printf( "      Average injection rate per node: %f\n", (double)header->regions[i].num_packets / (double)header->regions[i].num_cycles / (double)header->num_nodes );
542
                }
543
                printf( "  Size of header (B): %u\n", nt_get_headersize() );
544
                printf( "NT_TRACEFILE---------------------\n" );
545
        } else {
546
                printf( "NULL header passed to nt_print_header\n" );
547
        }
548
}
549
 
550
void nt_print_trheader() {
551
        nt_print_header( nt_input_trheader );
552
}
553
 
554
nt_header_t* nt_get_trheader() {
555
        if( nt_input_tracefile != NULL ) {
556
                return nt_input_trheader;
557
        } else {
558
                nt_error( "must open trace file with nt_open_trfile before header is available" );
559
        }
560
        return NULL;
561
}
562
 
563
float nt_get_trversion() {
564
        if( nt_input_tracefile != NULL ) {
565
                return nt_input_trheader->version;
566
        } else {
567
                nt_error( "must open trace file with nt_open_trfile before version is available" );
568
        }
569
        return 0.0f;
570
}
571
 
572
nt_packet_t* nt_packet_malloc() {
573
        // TODO: v1.1?
574
        // Allocate large array (1+ pages) to reduce # system calls
575
        return (nt_packet_t*) nt_checked_malloc( sizeof(nt_packet_t) );
576
}
577
 
578
nt_dependency_t* nt_dependency_malloc( unsigned char num_deps ) {
579
        // TODO: v1.1?
580
        // Allocate large array (1+ pages) to reduce # system calls
581
        return (nt_dependency_t*) nt_checked_malloc( num_deps * sizeof(nt_dependency_t) );
582
}
583
 
584
int nt_get_src_type( nt_packet_t* packet ) {
585
        return (int) ( packet->node_types >> 4 );
586
}
587
 
588
int nt_get_dst_type( nt_packet_t* packet ) {
589
        return (int) ( 0xF & packet->node_types );
590
}
591
 
592
const char* nt_node_type_to_string( int type ) {
593
        if( type < NT_NUM_NODE_TYPES ) {
594
                return nt_node_types[type];
595
        } else {
596
                return nt_node_types[NT_NUM_NODE_TYPES];
597
        }
598
}
599
 
600
int nt_get_packet_size( nt_packet_t* packet ) {
601
        if( packet->type < NT_NUM_PACKET_TYPES ) {
602
                return nt_packet_sizes[packet->type];
603
        } else {
604
                return nt_packet_sizes[0];
605
        }
606
}
607
 
608
const char* nt_packet_type_to_string( nt_packet_t* packet ) {
609
        if( packet->type < NT_NUM_PACKET_TYPES ) {
610
                return nt_packet_types[packet->type];
611
        } else {
612
                return nt_packet_types[0];
613
        }
614
}
615
 
616
nt_packet_t* nt_packet_copy( nt_packet_t* packet ) {
617
        if( packet != NULL ) {
618
                nt_packet_t* to_return = nt_packet_malloc();
619
                memcpy( to_return, packet, sizeof(nt_packet_t) );
620
                if( packet->num_deps > 0 ) {
621
                        to_return->deps = nt_dependency_malloc( to_return->num_deps );
622
                        memcpy( to_return->deps, packet->deps, sizeof(nt_dependency_t) * to_return->num_deps );
623
                }
624
                return to_return;
625
        }
626
        return NULL;
627
}
628
 
629
void nt_packet_free( nt_packet_t* packet ) {
630
        if( packet != NULL ) {
631
                if( packet->num_deps > 0 ) {
632
                        free( packet->deps );
633
                }
634
                free( packet );
635
        }
636
}
637
 
638
void nt_print_packet( nt_packet_t* packet ) {
639
        int i;
640
        if( packet != NULL ) {
641
                printf( "  ID:%u CYC:%llu SRC:%u DST:%u ADR:0x%08x TYP:%s NDEP:%u",
642
                                packet->id, packet->cycle, packet->src,
643
                                packet->dst, packet->addr, nt_packet_type_to_string( packet ),
644
                                packet->num_deps );
645
                for( i = 0; i < packet->num_deps; i++ ) {
646
                        printf( " %d", packet->deps[i] );
647
                }
648
                printf( "\n" );
649
        } else {
650
                printf( "WARNING: %s:%d: NULL packet printed!\n", __FILE__, __LINE__ );
651
        }
652
}
653
 
654
void nt_free_trheader( nt_header_t* header ) {
655
        if( header != NULL ) {
656
                if( header->regions != NULL ) {
657
                        free( header->regions );
658
                }
659
                if( header->notes != NULL ) {
660
                        free( header->notes );
661
                }
662
                free( header );
663
        }
664
}
665
 
666
int nt_get_headersize() {
667
 
668
        #pragma pack(push,1)
669
        struct nt_header_pack {
670
                unsigned int nt_magic;
671
                float version;
672
                char benchmark_name[NT_BMARK_NAME_LENGTH];
673
                unsigned char num_nodes;
674
                unsigned long long int num_cycles;
675
                unsigned long long int num_packets;
676
                unsigned int notes_length;  // Includes null-terminating char
677
                unsigned int num_regions;
678
                char padding[9];
679
        };
680
        #pragma pack(pop)
681
 
682
        if( nt_input_tracefile != NULL ) {
683
                int to_return = 0;
684
                to_return += sizeof(struct nt_header_pack);
685
                to_return += nt_input_trheader->notes_length;
686
                to_return += nt_input_trheader->num_regions * sizeof(nt_regionhead_t);
687
                return to_return;
688
        } else {
689
                nt_error( "must open trace file with nt_open_trfile before header is available" );
690
        }
691
        return -1;
692
}
693
 
694
void* _nt_checked_malloc( size_t n, const char* file, int line ) {
695
        void* ptr;
696
        ptr = malloc( n );
697
        if( ptr == NULL ) {
698
                fprintf( stderr, "ERROR: bad allocation at %s:%d\n", file, line );
699
                exit(0);
700
        }
701
        return ptr;
702
}
703
 
704
int nt_little_endian() {
705
        int to_return = 1;
706
        union {
707
                int number;
708
                char bytes[sizeof(int)];
709
        } u;
710
        unsigned int i;
711
        u.number = (int)0;
712
        for( i = 0; i < sizeof(int); i++ ) {
713
                u.number |= (int)(i + 1) << (8 * i);
714
        }
715
        for( i = 0; i < sizeof(int); i++ ) {
716
                if( (unsigned int)u.bytes[i] != i+1 ) {
717
                        to_return = 0;
718
                        break;
719
                }
720
        }
721
        return to_return;
722
}
723
 
724
void _nt_error( const char* str, const char* file, const int line ) {
725
#ifdef DEBUG_ON
726
        fprintf( stderr, "WARNING: In %s:%d: %s\n", file, line, str );
727
#else
728
        fprintf( stderr, "ERROR: In %s:%d: %s\n", file, line, str );
729
        exit(0);
730
#endif
731
}
732
 
733
// Backend functions for creating trace files
734
void nt_dump_header( nt_header_t* header, FILE* fp ) {
735
 
736
        #pragma pack(push,1)
737
        struct nt_header_pack {
738
                unsigned int nt_magic;
739
                float version;
740
                char benchmark_name[NT_BMARK_NAME_LENGTH];
741
                unsigned char num_nodes;
742
                unsigned char pad;
743
                unsigned long long int num_cycles;
744
                unsigned long long int num_packets;
745
                unsigned int notes_length;  // Includes null-terminating char
746
                unsigned int num_regions;
747
                char padding[8];
748
        };
749
        #pragma pack(pop)
750
 
751
        if( header != NULL ) {
752
                struct nt_header_pack* out_header = (struct nt_header_pack*) nt_checked_malloc( sizeof(struct nt_header_pack) );
753
                out_header->nt_magic = header->nt_magic;
754
                out_header->version = header->version;
755
                strcpy( out_header->benchmark_name, header->benchmark_name );
756
                out_header->num_nodes = header->num_nodes;
757
                out_header->num_cycles = header->num_cycles;
758
                out_header->num_packets = header->num_packets;
759
                out_header->notes_length = header->notes_length;
760
                out_header->num_regions = header->num_regions;
761
                fwrite( out_header, sizeof(struct nt_header_pack), 1, fp );
762
                fwrite( header->notes, sizeof(char), header->notes_length, fp );
763
                fwrite( header->regions, sizeof(nt_regionhead_t), header->num_regions, fp );
764
                free( out_header );
765
        } else {
766
                nt_error( "dumping NULL header" );
767
        }
768
}
769
 
770
void nt_dump_packet( nt_packet_t* packet, FILE* fp ) {
771
 
772
        #pragma pack(push,1)
773
        struct nt_read_pack {
774
                unsigned long long int cycle;
775
                unsigned int id;
776
                unsigned int addr;
777
                unsigned char type;
778
                unsigned char src;
779
                unsigned char dst;
780
                unsigned char node_types;
781
                unsigned char num_deps;
782
        };
783
        #pragma pack(pop)
784
 
785
        if( packet != NULL ) {
786
                fwrite( packet, sizeof(struct nt_read_pack), 1, fp );
787
                fwrite( packet->deps, sizeof(nt_dependency_t), packet->num_deps, fp );
788
        } else {
789
                nt_error( "dumping NULL packet" );
790
        }
791
}

powered by: WebSVN 2.1.0

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